From 936aa7ec938d76fab0df7ce7948ef13e227a64bb Mon Sep 17 00:00:00 2001 From: Aaron Schulz Date: Wed, 14 Sep 2016 10:09:36 -0700 Subject: [PATCH] Make DB snapshot commit errors include active methods Change-Id: I59e501528b104e797b36103fa18792f539d92a14 --- includes/db/Database.php | 42 ++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/includes/db/Database.php b/includes/db/Database.php index 6cfff0e6d1..3374d67d01 100644 --- a/includes/db/Database.php +++ b/includes/db/Database.php @@ -618,6 +618,25 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface { return $this->mTrxLevel ? $this->mTrxWriteCallers : []; } + protected function pendingWriteAndCallbackCallers() { + if ( !$this->mTrxLevel ) { + return []; + } + + $fnames = $this->mTrxWriteCallers; + foreach ( [ + $this->mTrxIdleCallbacks, + $this->mTrxPreCommitCallbacks, + $this->mTrxEndCallbacks + ] as $callbacks ) { + foreach ( $callbacks as $callback ) { + $fnames[] = $callback[1]; + } + } + + return $fnames; + } + public function isOpen() { return $this->mOpened; } @@ -3042,9 +3061,10 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface { public function flushSnapshot( $fname = __METHOD__ ) { if ( $this->writesOrCallbacksPending() || $this->explicitTrxActive() ) { // This only flushes transactions to clear snapshots, not to write data + $fnames = implode( ', ', $this->pendingWriteAndCallbackCallers() ); throw new DBUnexpectedError( $this, - "$fname: Cannot COMMIT to clear snapshot because writes are pending." + "$fname: Cannot COMMIT to clear snapshot because writes are pending ($fnames)." ); } @@ -3511,9 +3531,10 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface { public function getScopedLockAndFlush( $lockKey, $fname, $timeout ) { if ( $this->writesOrCallbacksPending() ) { // This only flushes transactions to clear snapshots, not to write data + $fnames = implode( ', ', $this->pendingWriteAndCallbackCallers() ); throw new DBUnexpectedError( $this, - "$fname: Cannot COMMIT to clear snapshot because writes are pending." + "$fname: Cannot COMMIT to clear snapshot because writes are pending ($fnames)." ); } @@ -3650,18 +3671,11 @@ abstract class DatabaseBase implements IDatabase, LoggerAwareInterface { if ( $this->mTrxLevel && $this->mTrxDoneWrites ) { trigger_error( "Uncommitted DB writes (transaction from {$this->mTrxFname})." ); } - $danglingCallbacks = array_merge( - $this->mTrxIdleCallbacks, - $this->mTrxPreCommitCallbacks, - $this->mTrxEndCallbacks - ); - if ( $danglingCallbacks ) { - $callers = []; - foreach ( $danglingCallbacks as $callbackInfo ) { - $callers[] = $callbackInfo[1]; - } - $callers = implode( ', ', $callers ); - trigger_error( "DB transaction callbacks still pending (from $callers)." ); + + $danglingWriters = $this->pendingWriteAndCallbackCallers(); + if ( $danglingWriters ) { + $fnames = implode( ', ', $danglingWriters ); + trigger_error( "DB transaction writes or callbacks still pending ($fnames)." ); } } } -- 2.20.1