* database. Example uses in core:
* @see LoadBalancer::reallyOpenConnection()
* @see ForeignDBRepo::getMasterDB()
- * @see WebInstaller_DBConnect::execute()
+ * @see WebInstallerDBConnect::execute()
*
* @since 1.18
*
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 ) {
$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;
}
/**
# 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 = '';
$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 );
# 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 {
$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;
}
}
+ # 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();
}
}
}
+ # 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 );
}
}