const ROUND_BEGINNING = 'within-begin';
const ROUND_COMMITTING = 'within-commit';
const ROUND_ROLLING_BACK = 'within-rollback';
+ const ROUND_COMMIT_CALLBACKS = 'within-commit-callbacks';
+ const ROUND_ROLLBACK_CALLBACKS = 'within-rollback-callbacks';
private static $loggerFields =
[ 'replLogger', 'connLogger', 'queryLogger', 'perfLogger' ];
final public function commitAll( $fname = __METHOD__, array $options = [] ) {
$this->commitMasterChanges( $fname, $options );
- $this->forEachLBCallMethod( 'commitAll', [ $fname ] );
+ $this->forEachLBCallMethod( 'flushMasterSnapshots', [ $fname ] );
+ $this->forEachLBCallMethod( 'flushReplicaSnapshots', [ $fname ] );
}
final public function beginMasterChanges( $fname = __METHOD__ ) {
/** @noinspection PhpUnusedLocalVariableInspection */
$scope = $this->getScopedPHPBehaviorForCommit(); // try to ignore client aborts
// Run pre-commit callbacks and suppress post-commit callbacks, aborting on failure
- $this->forEachLBCallMethod( 'finalizeMasterChanges' );
+ do {
+ $count = 0; // number of callbacks executed this iteration
+ $this->forEachLB( function ( ILoadBalancer $lb ) use ( &$count ) {
+ $count += $lb->finalizeMasterChanges();
+ } );
+ } while ( $count > 0 );
$this->trxRoundId = false;
// Perform pre-commit checks, aborting on failure
$this->forEachLBCallMethod( 'approveMasterChanges', [ $options ] );
// Actually perform the commit on all master DB connections and revert DBO_TRX
$this->forEachLBCallMethod( 'commitMasterChanges', [ $fname ] );
// Run all post-commit callbacks in a separate step
+ $this->trxRoundStage = self::ROUND_COMMIT_CALLBACKS;
$e = $this->executePostTransactionCallbacks();
$this->trxRoundStage = self::ROUND_CURSORY;
// Throw any last post-commit callback error
// Actually perform the rollback on all master DB connections and revert DBO_TRX
$this->forEachLBCallMethod( 'rollbackMasterChanges', [ $fname ] );
// Run all post-commit callbacks in a separate step
+ $this->trxRoundStage = self::ROUND_ROLLBACK_CALLBACKS;
$this->executePostTransactionCallbacks();
$this->trxRoundStage = self::ROUND_CURSORY;
}
* @return array
*/
final protected function baseLoadBalancerParams() {
+ if ( $this->trxRoundStage === self::ROUND_COMMIT_CALLBACKS ) {
+ $initStage = ILoadBalancer::STAGE_POSTCOMMIT_CALLBACKS;
+ } elseif ( $this->trxRoundStage === self::ROUND_ROLLBACK_CALLBACKS ) {
+ $initStage = ILoadBalancer::STAGE_POSTROLLBACK_CALLBACKS;
+ } else {
+ $initStage = null;
+ }
+
return [
'localDomain' => $this->localDomain,
'readOnlyReason' => $this->readOnlyReason,
// Defer ChronologyProtector construction in case setRequestInfo() ends up
// being called later (but before the first connection attempt) (T192611)
$this->getChronologyProtector()->initLB( $lb );
- }
+ },
+ 'roundStage' => $initStage
];
}