From ca8810e29d31c7a37723d32fb93e18e2e765ff29 Mon Sep 17 00:00:00 2001 From: Aaron Schulz Date: Mon, 19 Aug 2013 12:26:01 -0700 Subject: [PATCH] Added a few more trx sanity checks to DatabaseBase * Also track the caller that added the callbacks Change-Id: Idc4d9e4a89fcee28bd4b18ad6d8c6b09b9fe7e75 --- includes/db/Database.php | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/includes/db/Database.php b/includes/db/Database.php index 27e6dadb06..77002d6157 100644 --- a/includes/db/Database.php +++ b/includes/db/Database.php @@ -3069,7 +3069,7 @@ abstract class DatabaseBase implements IDatabase, DatabaseType { * @since 1.20 */ final public function onTransactionIdle( $callback ) { - $this->mTrxIdleCallbacks[] = $callback; + $this->mTrxIdleCallbacks[] = array( $callback, wfGetCaller() ); if ( !$this->mTrxLevel ) { $this->runOnTransactionIdleCallbacks(); } @@ -3088,7 +3088,7 @@ abstract class DatabaseBase implements IDatabase, DatabaseType { */ final public function onTransactionPreCommitOrIdle( $callback ) { if ( $this->mTrxLevel ) { - $this->mTrxPreCommitCallbacks[] = $callback; + $this->mTrxPreCommitCallbacks[] = array( $callback, wfGetCaller() ); } else { $this->onTransactionIdle( $callback ); // this will trigger immediately } @@ -3108,8 +3108,9 @@ abstract class DatabaseBase implements IDatabase, DatabaseType { $this->mTrxIdleCallbacks = array(); // recursion guard foreach ( $callbacks as $callback ) { try { + list( $phpCallback ) = $callback; $this->clearFlag( DBO_TRX ); // make each query its own transaction - call_user_func( $callback ); + call_user_func( $phpCallback ); $this->setFlag( $autoTrx ? DBO_TRX : 0 ); // restore automatic begin() } catch ( Exception $e ) {} } @@ -3132,7 +3133,8 @@ abstract class DatabaseBase implements IDatabase, DatabaseType { $this->mTrxPreCommitCallbacks = array(); // recursion guard foreach ( $callbacks as $callback ) { try { - call_user_func( $callback ); + list( $phpCallback ) = $callback; + call_user_func( $phpCallback ); } catch ( Exception $e ) {} } } while ( count( $this->mTrxPreCommitCallbacks ) ); @@ -3232,6 +3234,7 @@ abstract class DatabaseBase implements IDatabase, DatabaseType { if ( $this->mTrxDoneWrites ) { Profiler::instance()->transactionWritingOut( $this->mServer, $this->mDBname ); } + $this->mTrxDoneWrites = false; $this->runOnTransactionIdleCallbacks(); } @@ -3266,6 +3269,7 @@ abstract class DatabaseBase implements IDatabase, DatabaseType { if ( $this->mTrxDoneWrites ) { Profiler::instance()->transactionWritingOut( $this->mServer, $this->mDBname ); } + $this->mTrxDoneWrites = false; } /** @@ -3850,9 +3854,21 @@ abstract class DatabaseBase implements IDatabase, DatabaseType { return (string)$this->mConn; } + /** + * Run a few simple sanity checks + */ public function __destruct() { + if ( $this->mTrxLevel && $this->mTrxDoneWrites ) { + trigger_error( "Uncommitted DB writes (transaction from {$this->mTrxFname})." ); + } if ( count( $this->mTrxIdleCallbacks ) || count( $this->mTrxPreCommitCallbacks ) ) { - trigger_error( "Transaction idle or pre-commit callbacks still pending." ); // sanity + $callers = array(); + foreach ( $this->mTrxIdleCallbacks as $callbackInfo ) { + $callers[] = $callbackInfo[0]; + + } + $callers = implode( ', ', $callers ); + trigger_error( "DB transaction callbacks still pending (from $callers)." ); } } } -- 2.20.1