jenkins-bot has submitted this change and it was merged.

Change subject: Cleanups to DB transaction handling
......................................................................


Cleanups to DB transaction handling

* Only do requeries after automatic reconnection if there is no trx open 
instead.
  of doing possible half-broken changes and not fully updating trx state 
variables
* Also made trxLevel() no longer take an argument.
* Avoid clearing trx fields in some redundant places to make the code simpler
  Only mTrxLevel needs to be well tracked in various places. For the other 
fields,
  code just checks mTrxLevel before using those fields.
  They do need to be cleared in begin() though.
* Moved endAtomic() up next to startAtomic().
* Improved mTrxLevel docs

Change-Id: I12adfb4fcb28a4832facd63baee2283ead500bd2
---
M includes/db/Database.php
1 file changed, 47 insertions(+), 32 deletions(-)

Approvals:
  Chad: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/includes/db/Database.php b/includes/db/Database.php
index cd907e9..bcf5724 100644
--- a/includes/db/Database.php
+++ b/includes/db/Database.php
@@ -243,7 +243,6 @@
        protected $mTablePrefix;
        protected $mFlags;
        protected $mForeign;
-       protected $mTrxLevel = 0;
        protected $mErrorCount = 0;
        protected $mLBInfo = array();
        protected $mFakeSlaveLag = null, $mFakeMaster = false;
@@ -255,6 +254,14 @@
        protected $htmlErrors;
 
        protected $delimiter = ';';
+
+       /**
+        * Either 1 if a transaction is active or 0 otherwise.
+        * The other Trx fields may not be meaningfull if this is 0.
+        *
+        * @var int
+        */
+       protected $mTrxLevel = 0;
 
        /**
         * Remembers the function name given for starting the most recent 
transaction via begin().
@@ -385,16 +392,15 @@
        }
 
        /**
-        * Gets or sets the current transaction level.
+        * Gets the current transaction level.
         *
         * Historically, transactions were allowed to be "nested". This is no
         * longer supported, so this function really only returns a boolean.
         *
-        * @param int $level An integer (0 or 1), or omitted to leave it 
unchanged.
         * @return int The previous value
         */
-       public function trxLevel( $level = null ) {
-               return wfSetVar( $this->mTrxLevel, $level );
+       public function trxLevel() {
+               return $this->mTrxLevel;
        }
 
        /**
@@ -1023,9 +1029,9 @@
                # Try reconnecting if the connection was lost
                if ( false === $ret && $this->wasErrorReissuable() ) {
                        # Transaction is gone, like it or not
+                       $hadTrx = $this->mTrxLevel; // possible lost transaction
+                       wfDebug( "Connection lost, reconnecting...\n" );
                        $this->mTrxLevel = 0;
-                       $this->mTrxIdleCallbacks = array(); // cancel
-                       $this->mTrxPreCommitCallbacks = array(); // cancel
                        wfDebug( "Connection lost, reconnecting...\n" );
 
                        if ( $this->ping() ) {
@@ -1038,7 +1044,10 @@
                                        # Not a database error to lose a 
transaction after a minute or two
                                        wfLogDBError( "Connection lost and 
reconnected after {$elapsed}s, query: $sqlx\n" );
                                }
-                               $ret = $this->doQuery( $commentedSql );
+                               if ( !$hadTrx ) {
+                                       # Should be safe to silently retry
+                                       $ret = $this->doQuery( $commentedSql );
+                               }
                        } else {
                                wfDebug( "Failed\n" );
                        }
@@ -3223,6 +3232,7 @@
         *
         * @since 1.23
         * @param string $fname
+        * @throws DBError
         */
        final public function startAtomic( $fname = __METHOD__ ) {
                if ( !$this->mTrxLevel ) {
@@ -3232,6 +3242,32 @@
                }
 
                $this->mTrxAtomicLevels->push( $fname );
+       }
+
+       /**
+        * Ends an atomic section of SQL statements
+        *
+        * Ends the next section of atomic SQL statements and commits the 
transaction
+        * if necessary.
+        *
+        * @since 1.23
+        * @see DatabaseBase::startAtomic
+        * @param string $fname
+        * @throws DBError
+        */
+       final public function endAtomic( $fname = __METHOD__ ) {
+               if ( !$this->mTrxLevel ) {
+                       throw new DBUnexpectedError( $this, 'No atomic 
transaction is open.' );
+               }
+               if ( $this->mTrxAtomicLevels->isEmpty() ||
+                       $this->mTrxAtomicLevels->pop() !== $fname
+               ) {
+                       throw new DBUnexpectedError( $this, 'Invalid atomic 
section ended.' );
+               }
+
+               if ( $this->mTrxAtomicLevels->isEmpty() && 
$this->mTrxAutomaticAtomic ) {
+                       $this->commit( $fname, 'flush' );
+               }
        }
 
        /**
@@ -3245,6 +3281,7 @@
         * transaction was started automatically because of the DBO_TRX flag.
         *
         * @param $fname string
+        * @throws DBError
         */
        final public function begin( $fname = __METHOD__ ) {
                global $wgDebugDBTransactions;
@@ -3287,6 +3324,8 @@
                $this->mTrxAutomatic = false;
                $this->mTrxAutomaticAtomic = false;
                $this->mTrxAtomicLevels = new SplStack;
+               $this->mTrxIdleCallbacks = array();
+               $this->mTrxPreCommitCallbacks = array();
        }
 
        /**
@@ -3298,28 +3337,6 @@
        protected function doBegin( $fname ) {
                $this->query( 'BEGIN', $fname );
                $this->mTrxLevel = 1;
-       }
-
-       /**
-        * Ends an atomic section of SQL statements
-        *
-        * Ends the next section of atomic SQL statements and commits the 
transaction
-        * if necessary.
-        *
-        * @since 1.23
-        * @see DatabaseBase::startAtomic
-        * @param string $fname
-        */
-       final public function endAtomic( $fname = __METHOD__ ) {
-               if ( $this->mTrxAtomicLevels->isEmpty() ||
-                       $this->mTrxAtomicLevels->pop() !== $fname
-               ) {
-                       throw new DBUnexpectedError( $this, 'Invalid atomic 
section ended.' );
-               }
-
-               if ( $this->mTrxAtomicLevels->isEmpty() && 
$this->mTrxAutomaticAtomic ) {
-                       $this->commit( $fname, 'flush' );
-               }
        }
 
        /**
@@ -3359,7 +3376,6 @@
                if ( $this->mTrxDoneWrites ) {
                        Profiler::instance()->transactionWritingOut( 
$this->mServer, $this->mDBname );
                }
-               $this->mTrxDoneWrites = false;
                $this->runOnTransactionIdleCallbacks();
        }
 
@@ -3395,7 +3411,6 @@
                if ( $this->mTrxDoneWrites ) {
                        Profiler::instance()->transactionWritingOut( 
$this->mServer, $this->mDBname );
                }
-               $this->mTrxDoneWrites = false;
        }
 
        /**

-- 
To view, visit https://gerrit.wikimedia.org/r/93627
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I12adfb4fcb28a4832facd63baee2283ead500bd2
Gerrit-PatchSet: 3
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Aaron Schulz <[email protected]>
Gerrit-Reviewer: Chad <[email protected]>
Gerrit-Reviewer: jenkins-bot

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to