Enqueueing a DeferredUpdate while in a database transaction is problematic, because the DeferredUpdate may encounter an unexpected situation if the transaction is rolled back, but the update is kept in the queue and executed later in the request. For instance, a likely explanation for the exception thrown by LinksUpdate in T279832 is that the original transaction was rolled back, and the newly created page that the LinksUpdate was supposed to operate on was never committed to the database.
To avoid this, we could:
- Forbid DeferredUpdates being scheduled in a transaction. Existing code would need to be modified to accommodate this restriction, e.g. using IDatabase::onTransactionIdle callbacks or by converting to AutoCommitUpdate or MWCallableUpdate, which have rollback handling built in.
- Automatically de-queue all updates enqueued during a transaction, similar to the mechanism used by AutoCommitUpdate.
- Automatically postpone enqueueing updates until after the current transaction, using onTransactionIdle.