*/
protected $mTrxLevel = 0;
+ /**
+ * Either a short hexidecimal string if a transaction is active or ""
+ *
+ * @var string
+ */
+ protected $mTrxShortId = '';
+
/**
* Remembers the function name given for starting the most recent transaction via begin().
* Used to provide additional context for error reporting.
$this->mLastQuery = $sql;
if ( !$this->mDoneWrites && $this->isWriteQuery( $sql ) ) {
# Set a flag indicating that writes have been done
- wfDebug( __METHOD__ . ": Writes done: $sql\n" );
+ wfDebug( __METHOD__ . ': Writes done: ' . DatabaseBase::generalizeSQL( $sql ) . "\n" );
$this->mDoneWrites = true;
}
# Keep track of whether the transaction has write queries pending
if ( $this->mTrxLevel && !$this->mTrxDoneWrites && $this->isWriteQuery( $sql ) ) {
$this->mTrxDoneWrites = true;
- $id = spl_object_hash( $this );
- Profiler::instance()->transactionWritingIn( $this->mServer, $this->mDBname, $id );
+ Profiler::instance()->transactionWritingIn(
+ $this->mServer, $this->mDBname, $this->mTrxShortId );
}
$queryProf = '';
$queryProf = 'query: ' . substr( DatabaseBase::generalizeSQL( $sql ), 0, 255 );
$totalProf = 'DatabaseBase::query';
}
+ # Include query transaction state
+ $queryProf .= $this->mTrxShortId ? " [TRX#{$this->mTrxShortId}]" : "";
+
+ $trx = $this->mTrxLevel ? 'TRX=yes' : 'TRX=no';
wfProfileIn( $totalProf );
wfProfileIn( $queryProf );
}
# 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 {
* @return string
*/
protected function escapeLikeInternal( $s ) {
- $s = str_replace( '\\', '\\\\', $s );
- $s = $this->strencode( $s );
- $s = str_replace( array( '%', '_' ), array( '\%', '\_' ), $s );
-
- return $s;
+ return addcslashes( $s, '\%_' );
}
/**
}
}
- return " LIKE '" . $s . "' ";
+ return " LIKE {$this->addQuotes( $s )} ";
}
/**
$this->runOnTransactionPreCommitCallbacks();
$this->doCommit( $fname );
if ( $this->mTrxDoneWrites ) {
- $id = spl_object_hash( $this );
- Profiler::instance()->transactionWritingOut( $this->mServer, $this->mDBname, $id );
+ Profiler::instance()->transactionWritingOut(
+ $this->mServer, $this->mDBname, $this->mTrxShortId );
}
$this->runOnTransactionIdleCallbacks();
}
$this->mTrxAtomicLevels = new SplStack;
$this->mTrxIdleCallbacks = array();
$this->mTrxPreCommitCallbacks = array();
+ $this->mTrxShortId = wfRandomString( 12 );
}
/**
);
}
- if ( $flush !== 'flush' ) {
+ if ( $flush === 'flush' ) {
if ( !$this->mTrxLevel ) {
- wfWarn( "$fname: No transaction to commit, something got out of sync!" );
- } elseif ( $this->mTrxAutomatic ) {
- wfWarn( "$fname: Explicit commit of implicit transaction. Something may be out of sync!" );
+ return; // nothing to do
+ } elseif ( !$this->mTrxAutomatic ) {
+ wfWarn( "$fname: Flushing an explicit transaction, getting out of sync!" );
}
} else {
if ( !$this->mTrxLevel ) {
+ wfWarn( "$fname: No transaction to commit, something got out of sync!" );
return; // nothing to do
- } elseif ( !$this->mTrxAutomatic ) {
- wfWarn( "$fname: Flushing an explicit transaction, getting out of sync!" );
+ } elseif ( $this->mTrxAutomatic ) {
+ wfWarn( "$fname: Explicit commit of implicit transaction. Something may be out of sync!" );
}
}
$this->runOnTransactionPreCommitCallbacks();
$this->doCommit( $fname );
if ( $this->mTrxDoneWrites ) {
- $id = spl_object_hash( $this );
- Profiler::instance()->transactionWritingOut( $this->mServer, $this->mDBname, $id );
+ Profiler::instance()->transactionWritingOut(
+ $this->mServer, $this->mDBname, $this->mTrxShortId );
}
$this->runOnTransactionIdleCallbacks();
}
if ( $flush !== 'flush' ) {
if ( !$this->mTrxLevel ) {
wfWarn( "$fname: No transaction to rollback, something got out of sync!" );
+ return; // nothing to do
} elseif ( $this->mTrxAutomatic ) {
wfWarn( "$fname: Explicit rollback of implicit transaction. Something may be out of sync!" );
}
$this->mTrxPreCommitCallbacks = array(); // cancel
$this->mTrxAtomicLevels = new SplStack;
if ( $this->mTrxDoneWrites ) {
- $id = spl_object_hash( $this );
- Profiler::instance()->transactionWritingOut( $this->mServer, $this->mDBname, $id );
+ Profiler::instance()->transactionWritingOut(
+ $this->mServer, $this->mDBname, $this->mTrxShortId );
}
}