protected $mTrxPreCommitCallbacks = [];
/** @var array[] List of (callable, method name) */
protected $mTrxEndCallbacks = [];
+ /** @var bool Whether to suppress triggering of post-commit callbacks */
+ protected $suppressPostCommitCallbacks = false;
protected $mTablePrefix;
protected $mSchema;
}
public function close() {
- if ( count( $this->mTrxIdleCallbacks ) ) { // sanity
- throw new MWException( "Transaction idle callbacks still pending." );
- }
if ( $this->mConn ) {
if ( $this->trxLevel() ) {
if ( !$this->mTrxAutomatic ) {
$closed = $this->closeConnection();
$this->mConn = false;
+ } elseif ( $this->mTrxIdleCallbacks || $this->mTrxEndCallbacks ) { // sanity
+ throw new MWException( "Transaction callbacks still pending." );
} else {
$closed = true;
}
* queries. If a deadlock occurs during the processing, the transaction
* will be rolled back and the callback function will be called again.
*
+ * Avoid using this method outside of Job or Maintenance classes.
+ *
* Usage:
* $dbw->deadlockLoop( callback, ... );
*
* Extra arguments are passed through to the specified callback function.
+ * This method requires that no transactions are already active to avoid
+ * causing premature commits or exceptions.
*
* Returns whatever the callback function returned on its successful,
* iteration, or false on error, for example if the retry limit was
* reached.
+ *
* @return mixed
* @throws DBUnexpectedError
* @throws Exception
return false;
}
+ public function serverIsReadOnly() {
+ return false;
+ }
+
final public function onTransactionResolution( callable $callback ) {
if ( !$this->mTrxLevel ) {
throw new DBUnexpectedError( $this, "No transaction is active." );
}
/**
- * Actually any "on transaction idle" callbacks.
+ * Whether to disable running of post-commit callbacks
+ *
+ * This method should not be used outside of Database/LoadBalancer
+ *
+ * @param bool $suppress
+ * @since 1.28
+ */
+ final public function setPostCommitCallbackSupression( $suppress ) {
+ $this->suppressPostCommitCallbacks = $suppress;
+ }
+
+ /**
+ * Actually run and consume any "on transaction idle/resolution" callbacks.
+ *
+ * This method should not be used outside of Database/LoadBalancer
*
* @param integer $trigger IDatabase::TRIGGER_* constant
* @since 1.20
*/
- protected function runOnTransactionIdleCallbacks( $trigger ) {
+ public function runOnTransactionIdleCallbacks( $trigger ) {
+ if ( $this->suppressPostCommitCallbacks ) {
+ return;
+ }
+
$autoTrx = $this->getFlag( DBO_TRX ); // automatic begin() enabled?
$e = $ePrior = null; // last exception
$this->mTrxIdleCallbacks,
$this->mTrxEndCallbacks // include "transaction resolution" callbacks
);
- $this->mTrxIdleCallbacks = []; // recursion guard
- $this->mTrxEndCallbacks = []; // recursion guard
+ $this->mTrxIdleCallbacks = []; // consumed (and recursion guard)
+ $this->mTrxEndCallbacks = []; // consumed (recursion guard)
foreach ( $callbacks as $callback ) {
try {
list( $phpCallback ) = $callback;
}
/**
- * Actually any "on transaction pre-commit" callbacks.
+ * Actually run and consume any "on transaction pre-commit" callbacks.
*
* This method should not be used outside of Database/LoadBalancer
*
$e = $ePrior = null; // last exception
do { // callbacks may add callbacks :)
$callbacks = $this->mTrxPreCommitCallbacks;
- $this->mTrxPreCommitCallbacks = []; // recursion guard
+ $this->mTrxPreCommitCallbacks = []; // consumed (and recursion guard)
foreach ( $callbacks as $callback ) {
try {
list( $phpCallback ) = $callback;
$this->mTrxAutomatic = false;
$this->mTrxAutomaticAtomic = false;
$this->mTrxAtomicLevels = [];
- $this->mTrxIdleCallbacks = [];
- $this->mTrxPreCommitCallbacks = [];
$this->mTrxShortId = wfRandomString( 12 );
$this->mTrxWriteDuration = 0.0;
$this->mTrxWriteCallers = [];