- foreach ( $this->mConns as $conns2 ) {
- foreach ( $conns2 as $conns3 ) {
- /** @var DatabaseBase[] $conns3 */
- foreach ( $conns3 as $conn ) {
- if ( $conn->trxLevel() ) {
- $conn->commit( $fname, 'flush' );
- }
- }
+ $this->forEachOpenConnection( function ( DatabaseBase $conn ) use ( $fname ) {
+ $conn->commit( $fname, 'flush' );
+ } );
+ }
+
+ /**
+ * Perform all pre-commit callbacks that remain part of the atomic transactions
+ * and disable any post-commit callbacks until runMasterPostCommitCallbacks()
+ * @since 1.28
+ */
+ public function runMasterPreCommitCallbacks() {
+ $this->forEachOpenMasterConnection( function ( DatabaseBase $conn ) {
+ // Any error will cause all DB transactions to be rolled back together.
+ $conn->runOnTransactionPreCommitCallbacks();
+ // Defer post-commit callbacks until COMMIT finishes for all DBs.
+ $conn->setPostCommitCallbackSupression( true );
+ } );
+ }
+
+ /**
+ * Perform all pre-commit checks for things like replication safety
+ * @param array $options Includes:
+ * - maxWriteDuration : max write query duration time in seconds
+ * @throws DBTransactionError
+ * @since 1.28
+ */
+ public function approveMasterChanges( array $options ) {
+ $limit = isset( $options['maxWriteDuration'] ) ? $options['maxWriteDuration'] : 0;
+ $this->forEachOpenMasterConnection( function ( DatabaseBase $conn ) use ( $limit ) {
+ // Assert that the time to replicate the transaction will be sane.
+ // If this fails, then all DB transactions will be rollback back together.
+ $time = $conn->pendingWriteQueryDuration();
+ if ( $limit > 0 && $time > $limit ) {
+ throw new DBTransactionError(
+ $conn,
+ wfMessage( 'transaction-duration-limit-exceeded', $time, $limit )->text()
+ );