Make unclosed transaction errors more useful
authorGergő Tisza <tgr.huwiki@gmail.com>
Tue, 9 Oct 2018 02:04:59 +0000 (19:04 -0700)
committerGergő Tisza <gtisza@wikimedia.org>
Tue, 9 Oct 2018 17:50:17 +0000 (17:50 +0000)
Move unclosed transaction error reporting to Database so it can
include information about the caller that started the transaction.

Change-Id: I834d957f172c03005de522f3029bb634b3c7220e

includes/libs/rdbms/database/DBConnRef.php
includes/libs/rdbms/database/Database.php
includes/libs/rdbms/database/IDatabase.php
includes/libs/rdbms/loadbalancer/LoadBalancer.php

index 0de90c9..ba251ba 100644 (file)
@@ -69,6 +69,10 @@ class DBConnRef implements IDatabase {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
+       public function assertNoOpenTransactions() {
+               return $this->__call( __FUNCTION__, func_get_args() );
+       }
+
        public function tablePrefix( $prefix = null ) {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
index 1b3e6cc..a091242 100644 (file)
@@ -1347,6 +1347,16 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                }
        }
 
+       public function assertNoOpenTransactions() {
+               if ( $this->explicitTrxActive() ) {
+                       throw new DBTransactionError(
+                               $this,
+                               "Explicit transaction still active. A caller may have caught an error. "
+                               . "Open transactions: " . $this->flatAtomicSectionList()
+                       );
+               }
+       }
+
        /**
         * Determine whether or not it is safe to retry queries after a database
         * connection is lost
index 39fbbca..0608253 100644 (file)
@@ -164,6 +164,13 @@ interface IDatabase {
         */
        public function explicitTrxActive();
 
+       /**
+        * Assert that all explicit transactions or atomic sections have been closed.
+        * @throws DBTransactionError
+        * @since 1.32
+        */
+       public function assertNoOpenTransactions();
+
        /**
         * Get/set the table prefix.
         * @param string|null $prefix The table prefix to set, or omitted to leave it unchanged.
index f36d98e..b4c7c8f 100644 (file)
@@ -1337,12 +1337,7 @@ class LoadBalancer implements ILoadBalancer {
                        // If atomic sections or explicit transactions are still open, some caller must have
                        // caught an exception but failed to properly rollback any changes. Detect that and
                        // throw and error (causing rollback).
-                       if ( $conn->explicitTrxActive() ) {
-                               throw new DBTransactionError(
-                                       $conn,
-                                       "Explicit transaction still active. A caller may have caught an error."
-                               );
-                       }
+                       $conn->assertNoOpenTransactions();
                        // Assert that the time to replicate the transaction will be sane.
                        // If this fails, then all DB transactions will be rollback back together.
                        $time = $conn->pendingWriteQueryDuration( $conn::ESTIMATE_DB_APPLY );