Index: includes/database.mysql.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/Attic/database.mysql.inc,v
retrieving revision 1.89.2.1
diff -u -p -r1.89.2.1 database.mysql.inc
--- includes/database.mysql.inc	21 Jul 2009 08:52:29 -0000	1.89.2.1
+++ includes/database.mysql.inc	28 Sep 2009 23:58:33 -0000
@@ -105,21 +105,44 @@ function _db_query($query, $debug = 0) {
     $query = '/* '. $name .' : '. $bt[2]['function'] .' */ '. $query;
   }
 
-  $result = mysql_query($query, $active_db);
+  $retry = 0;
 
-  if (variable_get('dev_query', 0)) {
-    $query = $bt[2]['function'] ."\n". $query;
-    list($usec, $sec) = explode(' ', microtime());
-    $stop = (float)$usec + (float)$sec;
-    $diff = $stop - $timer;
-    $queries[] = array($query, $diff);
-  }
+  do {
+    $result = mysql_query($query, $active_db);
+    $errno = mysql_errno($active_db);
+
+    if (variable_get('dev_query', 0)) {
+      $query = $bt[2]['function'] ."\n". $query;
+      list($usec, $sec) = explode(' ', microtime());
+      $stop = (float)$usec + (float)$sec;
+      $diff = $stop - $timer;
+      $queries[] = array($query, $diff);
+    }
+
+    // Handle transient errors.
+    // If we can handle this error, then increment the counter, so we run again. Otherwise
+    // use the default case to exit the while loop and return an error as per normal.
+    switch($errno) {
+      case 1205:    // Lock wait timeout exceeded; try restarting transaction
+      case 1213:    // Deadlock found when trying to get lock; try restarting transaction
+      case 1614:    // Transaction branch was rolled back: deadlock was detected
+      case 2013:    // Lost connection to MySQL server during query
+        $retry++;   // Increment counter.
+        break;
+
+      // If not an error we can handle (or not an error!) exit the loop.
+      // We cal deal with fall-out later, as errno is set.
+      default:
+        $retry = 2;
+        break;
+    }
+  } while ($retry < 2);
 
   if ($debug) {
     print '<p>query: '. $query .'<br />error:'. mysql_error($active_db) .'</p>';
   }
 
-  if (!mysql_errno($active_db)) {
+  if (!$errno) {
     return $result;
   }
   else {
Index: includes/database.mysqli.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/Attic/database.mysqli.inc,v
retrieving revision 1.54.2.1
diff -u -p -r1.54.2.1 database.mysqli.inc
--- includes/database.mysqli.inc	21 Jul 2009 08:52:30 -0000	1.54.2.1
+++ includes/database.mysqli.inc	28 Sep 2009 23:58:34 -0000
@@ -105,21 +105,44 @@ function _db_query($query, $debug = 0) {
     $query = '/* '. $name .' : '. $bt[2]['function'] .' */ '. $query;
   }
 
-  $result = mysqli_query($active_db, $query);
+  $retry = 0;
 
-  if (variable_get('dev_query', 0)) {
-    $query = $bt[2]['function'] ."\n". $query;
-    list($usec, $sec) = explode(' ', microtime());
-    $stop = (float)$usec + (float)$sec;
-    $diff = $stop - $timer;
-    $queries[] = array($query, $diff);
-  }
+  do {
+    $result = mysqli_query($query, $active_db);
+    $errno = mysqli_errno($active_db);
+
+    if (variable_get('dev_query', 0)) {
+      $query = $bt[2]['function'] ."\n". $query;
+      list($usec, $sec) = explode(' ', microtime());
+      $stop = (float)$usec + (float)$sec;
+      $diff = $stop - $timer;
+      $queries[] = array($query, $diff);
+    }
+
+    // Handle transient errors.
+    // If we can handle this error, then increment the counter, so we run again. Otherwise
+    // use the default case to exit the while loop and return an error as per normal.
+    switch($errno) {
+      case 1205:    // Lock wait timeout exceeded; try restarting transaction
+      case 1213:    // Deadlock found when trying to get lock; try restarting transaction
+      case 1614:    // Transaction branch was rolled back: deadlock was detected
+      case 2013:    // Lost connection to MySQL server during query
+        $retry++;   // Increment counter.
+        break;
+
+      // If not an error we can handle (or not an error!) exit the loop.
+      // We cal deal with fall-out later, as errno is set.
+      default:
+        $retry = 2;
+        break;
+    }
+  } while ($retry < 2);
 
   if ($debug) {
     print '<p>query: '. $query .'<br />error:'. mysqli_error($active_db) .'</p>';
   }
 
-  if (!mysqli_errno($active_db)) {
+  if (!$errno) {
     return $result;
   }
   else {
