From: Gergő Tisza Date: Tue, 9 Oct 2018 02:04:59 +0000 (-0700) Subject: Make unclosed transaction errors more useful X-Git-Tag: 1.34.0-rc.0~3856^2 X-Git-Url: https://git.cyclocoop.org/%7B%24admin_url%7Dmembres/%7B%7B%20url_for%28%27vote%27%2C%20idvote=vote.voteid%29%20%7D%7D?a=commitdiff_plain;h=cebdd50a49a2169482fbdd63f080814a4c033dc7;p=lhc%2Fweb%2Fwiklou.git Make unclosed transaction errors more useful Move unclosed transaction error reporting to Database so it can include information about the caller that started the transaction. Change-Id: I834d957f172c03005de522f3029bb634b3c7220e --- diff --git a/includes/libs/rdbms/database/DBConnRef.php b/includes/libs/rdbms/database/DBConnRef.php index 0de90c9d04..ba251babd7 100644 --- a/includes/libs/rdbms/database/DBConnRef.php +++ b/includes/libs/rdbms/database/DBConnRef.php @@ -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() ); } diff --git a/includes/libs/rdbms/database/Database.php b/includes/libs/rdbms/database/Database.php index 1b3e6cc5da..a0912425b9 100644 --- a/includes/libs/rdbms/database/Database.php +++ b/includes/libs/rdbms/database/Database.php @@ -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 diff --git a/includes/libs/rdbms/database/IDatabase.php b/includes/libs/rdbms/database/IDatabase.php index 39fbbcaccd..0608253ef7 100644 --- a/includes/libs/rdbms/database/IDatabase.php +++ b/includes/libs/rdbms/database/IDatabase.php @@ -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. diff --git a/includes/libs/rdbms/loadbalancer/LoadBalancer.php b/includes/libs/rdbms/loadbalancer/LoadBalancer.php index f36d98e70d..b4c7c8fcc1 100644 --- a/includes/libs/rdbms/loadbalancer/LoadBalancer.php +++ b/includes/libs/rdbms/loadbalancer/LoadBalancer.php @@ -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 );