[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [OSSTEST PATCH 6/7] Database locking: Tcl: Retry only on DEADLOCK DETECTED



Use the new errorCode coming out of db-execute* to tell when the error
is that we got a database deadlock, which is the situation in which we
should retry.

This involves combining the two catch blocks, so that there is only
one error handling strategy.  Previously errors on COMMIT would be
retried and others would not.  Now errors anywhere might be retried
but only if the DB indicated deadlock.

We now unconditionally execute ROLLBACK.  This is more correct, since
we always previously executed BEGIN.

And, we pass the errorInfo and errorCode from the $body to the caller.

I have tested this with a test db instance, using contrived means to
generate a database deadlock, and it does actually retry.

Signed-off-by: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>
---
 tcl/JobDB-Executive.tcl |   30 ++++++++++++++++--------------
 1 file changed, 16 insertions(+), 14 deletions(-)

diff --git a/tcl/JobDB-Executive.tcl b/tcl/JobDB-Executive.tcl
index ed9abbb..63db4f0 100644
--- a/tcl/JobDB-Executive.tcl
+++ b/tcl/JobDB-Executive.tcl
@@ -283,25 +283,27 @@ proc transaction {tables script} {
            db-execute "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE"
            lock-tables $tables
            uplevel 1 $script
+           db-execute COMMIT
        } result]
-       if {!$rc} {
-           if {[catch {
-               db-execute COMMIT
-           } emsg]} {
-               puts "commit failed: $emsg; retrying ..."
-               db-execute ROLLBACK
-               if {[incr retries -1] <= 0} {
-                   error \
- "commit failed, too many retries: $emsg\n$errorInfo\n$errorCode\n"
+       set ei $errorInfo
+       set ec $errorCode
+       if {$rc} {
+           db-execute ROLLBACK
+           switch -glob $errorCode {
+               {OSSTEST-PSQL * 40P01} {
+                   # DEADLOCK DETECTED
+                   puts "transaction deadlock ($result) retrying ..."
+                   if {[incr retries -1] <= 0} {
+                       error \
+ "transaction failed, too many retries: $result\n$errorInfo\n$errorCode\n"
+                   }
+                   after 500
+                   continue
                }
-               after 500
-               continue
            }
-       } else {
-           db-execute ROLLBACK
        }
         db-close
-       return -code $rc $result
+       return -code $rc -errorinfo $ei -errorcode $ec $result
     }
 }
 
-- 
1.7.10.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.