3 use Wikimedia\Rdbms\IDatabase
;
6 * Deferrable Update for closure/callback updates that should use auto-commit mode
9 class AutoCommitUpdate
implements DeferrableUpdate
, DeferrableCallback
{
14 /** @var callable|null */
18 * @param IDatabase $dbw DB handle; update aborts if a transaction now this rolls back
19 * @param string $fname Caller name (usually __METHOD__)
20 * @param callable $callback Callback that takes (IDatabase, method name string)
21 * @param IDatabase[] $conns Abort if a transaction now on one of these rolls back [optional]
23 public function __construct( IDatabase
$dbw, $fname, callable
$callback, array $conns = [] ) {
25 $this->fname
= $fname;
26 $this->callback
= $callback;
27 // Register DB connections for which uncommitted changes are related to this update
29 foreach ( $conns as $conn ) {
30 if ( $conn->trxLevel() ) {
31 $conn->onTransactionResolution( [ $this, 'cancelOnRollback' ], $fname );
36 public function doUpdate() {
37 if ( !$this->callback
) {
41 $autoTrx = $this->dbw
->getFlag( DBO_TRX
);
42 $this->dbw
->clearFlag( DBO_TRX
);
44 /** @var Exception $e */
46 ( $this->callback
)( $this->dbw
, $this->fname
);
47 } catch ( Exception
$e ) {
50 $this->dbw
->setFlag( DBO_TRX
);
58 * @private This method is public so that it works with onTransactionResolution()
61 public function cancelOnRollback( $trigger ) {
62 if ( $trigger === IDatabase
::TRIGGER_ROLLBACK
) {
63 $this->callback
= null;
67 public function getOrigin() {