$autoTrx = $this->getFlag( DBO_TRX ); // automatic begin() enabled?
/** @var Exception $e */
- $e = $ePrior = null; // last exception
+ $e = null; // first exception
do { // callbacks may add callbacks :)
$callbacks = array_merge(
$this->mTrxIdleCallbacks,
} else {
$this->clearFlag( DBO_TRX ); // restore auto-commit
}
- } catch ( Exception $e ) {
- if ( $ePrior ) {
- MWExceptionHandler::logException( $ePrior );
- }
- $ePrior = $e;
+ } catch ( Exception $ex ) {
+ MWExceptionHandler::logException( $ex );
+ $e = $e ?: $ex;
// Some callbacks may use startAtomic/endAtomic, so make sure
// their transactions are ended so other callbacks don't fail
if ( $this->trxLevel() ) {
} while ( count( $this->mTrxIdleCallbacks ) );
if ( $e instanceof Exception ) {
- throw $e; // re-throw any last exception
+ throw $e; // re-throw any first exception
}
}
* This method should not be used outside of Database/LoadBalancer
*
* @since 1.22
+ * @throws Exception
*/
public function runOnTransactionPreCommitCallbacks() {
- $e = $ePrior = null; // last exception
+ $e = null; // first exception
do { // callbacks may add callbacks :)
$callbacks = $this->mTrxPreCommitCallbacks;
$this->mTrxPreCommitCallbacks = []; // consumed (and recursion guard)
try {
list( $phpCallback ) = $callback;
call_user_func( $phpCallback );
- } catch ( Exception $e ) {
- if ( $ePrior ) {
- MWExceptionHandler::logException( $ePrior );
- }
- $ePrior = $e;
+ } catch ( Exception $ex ) {
+ MWExceptionHandler::logException( $ex );
+ $e = $e ?: $ex;
}
}
} while ( count( $this->mTrxPreCommitCallbacks ) );
if ( $e instanceof Exception ) {
- throw $e; // re-throw any last exception
+ throw $e; // re-throw any first exception
}
}
* @param string $fname Caller name
* @param array $options Options map:
* - maxWriteDuration: abort if more than this much time was spent in write queries
+ * @throws Exception
*/
public function commitMasterChanges( $fname = __METHOD__, array $options = [] ) {
// Perform all pre-commit callbacks, aborting on failure
// Actually perform the commit on all master DB connections
$this->forEachLBCallMethod( 'commitMasterChanges', [ $fname ] );
// Run all post-commit callbacks
- $this->forEachLBCallMethod( 'runMasterPostCommitCallbacks' );
+ /** @var Exception $e */
+ $e = null; // first callback exception
+ $this->forEachLB( function ( LoadBalancer $lb ) use ( &$e ) {
+ $ex = $lb->runMasterPostCommitCallbacks();
+ $e = $e ?: $ex;
+ } );
// Commit any dangling DBO_TRX transactions from callbacks on one DB to another DB
$this->forEachLBCallMethod( 'commitMasterChanges', [ $fname ] );
+ // Throw any last post-commit callback error
+ if ( $e instanceof Exception ) {
+ throw $e;
+ }
}
/**
/**
* Issue all pending post-commit callbacks
+ * @return Exception|null The first exception or null if there were none
* @since 1.28
*/
public function runMasterPostCommitCallbacks() {
- $this->forEachOpenMasterConnection( function ( DatabaseBase $db ) {
+ $e = null; // first exception
+ $this->forEachOpenMasterConnection( function ( DatabaseBase $db ) use ( &$e ) {
$db->setPostCommitCallbackSupression( false );
- $db->runOnTransactionIdleCallbacks( IDatabase::TRIGGER_COMMIT );
+ try {
+ $db->runOnTransactionIdleCallbacks( IDatabase::TRIGGER_COMMIT );
+ } catch ( Exception $ex ) {
+ $e = $e ?: $ex;
+ }
} );
+
+ return $e;
}
/**