From d15810264161977440df08c9c3a9f60774ad1f0d Mon Sep 17 00:00:00 2001
From: Jared Hancock <jared@osticket.com>
Date: Thu, 23 Oct 2014 13:25:31 -0500
Subject: [PATCH] Rollback to autocommit, except for sequence  iteration

Keeping the transaction active for the entire request increases the
likelihood of a deadlock on Galera clusters.
---
 include/class.sequence.php |  5 +++++
 include/mysqli.php         | 19 +++++++------------
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/include/class.sequence.php b/include/class.sequence.php
index 1b3fc3182..cc27801c5 100644
--- a/include/class.sequence.php
+++ b/include/class.sequence.php
@@ -151,6 +151,9 @@ class Sequence extends VerySimpleModel {
      * and assured to be session-wise atomic before the value is returned.
      */
     function __next($digits=false) {
+        // Ensure this block is executed in a single transaction
+        db_autocommit(false);
+
         // Lock the database object -- this is important to handle concurrent
         // requests for new numbers
         static::objects()->filter(array('id'=>$this->id))->lock()->one();
@@ -161,6 +164,8 @@ class Sequence extends VerySimpleModel {
         $this->updated = SqlFunction::NOW();
         $this->save();
 
+        db_autocommit(true);
+
         return $next;
     }
 
diff --git a/include/mysqli.php b/include/mysqli.php
index 71681975c..ed70cd82e 100644
--- a/include/mysqli.php
+++ b/include/mysqli.php
@@ -76,18 +76,7 @@ function db_connect($host, $user, $passwd, $options = array()) {
 
     @db_set_variable('sql_mode', '');
 
-    // Start a new transaction -- for performance. Transactions are always
-    // committed at shutdown (below)
-    $__db->autocommit(false);
-
-    // Auto commit the transaction at shutdown and re-enable statement-level
-    // autocommit
-    register_shutdown_function(function() {
-        global $__db, $err;
-        if (!$__db->commit())
-            $err = 'Unable to save changes to database';
-        $__db->autocommit(true);
-    });
+    $__db->autocommit(true);
 
     // Use connection timing to seed the random number generator
     Misc::__rand_seed((microtime(true) - $start) * 1000000);
@@ -95,6 +84,12 @@ function db_connect($host, $user, $passwd, $options = array()) {
     return $__db;
 }
 
+function db_autocommit($enable=true) {
+    global $__db;
+
+    return $__db->autocommit($enable);
+}
+
 function db_close() {
     global $__db;
     return @$__db->close();
-- 
GitLab