X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2Fdb%2FDatabase.php;h=16e1ef231d6ce91e1f07fde62dc2140a45d61143;hb=de1f04ace13a68904a9db7f83ee1a73b52878385;hp=b502bb9874ce882b9a94b890c056863bac568ba9;hpb=280cb03b4d87e864a723686daf5d1699b3566ec1;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/db/Database.php b/includes/db/Database.php index b502bb9874..16e1ef231d 100644 --- a/includes/db/Database.php +++ b/includes/db/Database.php @@ -806,7 +806,7 @@ abstract class DatabaseBase implements IDatabase, DatabaseType { * database. Example uses in core: * @see LoadBalancer::reallyOpenConnection() * @see ForeignDBRepo::getMasterDB() - * @see WebInstaller_DBConnect::execute() + * @see WebInstallerDBConnect::execute() * * @since 1.18 * @@ -926,7 +926,6 @@ abstract class DatabaseBase implements IDatabase, DatabaseType { if ( count( $this->mTrxIdleCallbacks ) ) { // sanity throw new MWException( "Transaction idle callbacks still pending." ); } - $this->mOpened = false; if ( $this->mConn ) { if ( $this->trxLevel() ) { if ( !$this->mTrxAutomatic ) { @@ -937,13 +936,14 @@ abstract class DatabaseBase implements IDatabase, DatabaseType { $this->commit( __METHOD__, 'flush' ); } - $ret = $this->closeConnection(); + $closed = $this->closeConnection(); $this->mConn = false; - - return $ret; } else { - return true; + $closed = true; } + $this->mOpened = false; + + return $closed; } /** @@ -1054,7 +1054,8 @@ abstract class DatabaseBase implements IDatabase, DatabaseType { # Keep track of whether the transaction has write queries pending if ( $this->mTrxLevel && !$this->mTrxDoneWrites && $this->isWriteQuery( $sql ) ) { $this->mTrxDoneWrites = true; - Profiler::instance()->transactionWritingIn( $this->mServer, $this->mDBname ); + $id = spl_object_hash( $this ); + Profiler::instance()->transactionWritingIn( $this->mServer, $this->mDBname, $id ); } $queryProf = ''; @@ -1088,6 +1089,11 @@ abstract class DatabaseBase implements IDatabase, DatabaseType { $queryId = MWDebug::query( $sql, $fname, $isMaster ); + # Avoid fatals if close() was called + if ( !$this->isOpen() ) { + throw new DBUnexpectedError( $this, "DB connection was already closed." ); + } + # Do the query and handle errors $ret = $this->doQuery( $commentedSql ); @@ -1098,20 +1104,25 @@ abstract class DatabaseBase implements IDatabase, DatabaseType { # Transaction is gone, like it or not $hadTrx = $this->mTrxLevel; // possible lost transaction $this->mTrxLevel = 0; + $this->mTrxIdleCallbacks = array(); // bug 65263 + $this->mTrxPreCommitCallbacks = array(); // bug 65263 wfDebug( "Connection lost, reconnecting...\n" ); if ( $this->ping() ) { + global $wgRequestTime; wfDebug( "Reconnected\n" ); $sqlx = substr( $commentedSql, 0, 500 ); $sqlx = strtr( $sqlx, "\t\n", ' ' ); - global $wgRequestTime; $elapsed = round( microtime( true ) - $wgRequestTime, 3 ); if ( $elapsed < 300 ) { # Not a database error to lose a transaction after a minute or two wfLogDBError( "Connection lost and reconnected after {$elapsed}s, query: $sqlx" ); } - if ( !$hadTrx ) { - # Should be safe to silently retry + if ( $hadTrx ) { + # Leave $ret as false and let an error be reported. + # Callers may catch the exception and continue to use the DB. + } else { + # Should be safe to silently retry (no trx and thus no callbacks) $ret = $this->doQuery( $commentedSql ); } } else { @@ -3405,11 +3416,17 @@ abstract class DatabaseBase implements IDatabase, DatabaseType { $this->runOnTransactionPreCommitCallbacks(); $this->doCommit( $fname ); if ( $this->mTrxDoneWrites ) { - Profiler::instance()->transactionWritingOut( $this->mServer, $this->mDBname ); + $id = spl_object_hash( $this ); + Profiler::instance()->transactionWritingOut( $this->mServer, $this->mDBname, $id ); } $this->runOnTransactionIdleCallbacks(); } + # Avoid fatals if close() was called + if ( !$this->isOpen() ) { + throw new DBUnexpectedError( $this, "DB connection was already closed." ); + } + $this->doBegin( $fname ); $this->mTrxFname = $fname; $this->mTrxDoneWrites = false; @@ -3468,10 +3485,16 @@ abstract class DatabaseBase implements IDatabase, DatabaseType { } } + # Avoid fatals if close() was called + if ( !$this->isOpen() ) { + throw new DBUnexpectedError( $this, "DB connection was already closed." ); + } + $this->runOnTransactionPreCommitCallbacks(); $this->doCommit( $fname ); if ( $this->mTrxDoneWrites ) { - Profiler::instance()->transactionWritingOut( $this->mServer, $this->mDBname ); + $id = spl_object_hash( $this ); + Profiler::instance()->transactionWritingOut( $this->mServer, $this->mDBname, $id ); } $this->runOnTransactionIdleCallbacks(); } @@ -3517,12 +3540,18 @@ abstract class DatabaseBase implements IDatabase, DatabaseType { } } + # Avoid fatals if close() was called + if ( !$this->isOpen() ) { + throw new DBUnexpectedError( $this, "DB connection was already closed." ); + } + $this->doRollback( $fname ); $this->mTrxIdleCallbacks = array(); // cancel $this->mTrxPreCommitCallbacks = array(); // cancel $this->mTrxAtomicLevels = new SplStack; if ( $this->mTrxDoneWrites ) { - Profiler::instance()->transactionWritingOut( $this->mServer, $this->mDBname ); + $id = spl_object_hash( $this ); + Profiler::instance()->transactionWritingOut( $this->mServer, $this->mDBname, $id ); } }