/** @var string Atomic section is cancelable */
const ATOMIC_CANCELABLE = 'cancelable';
- /** @var string Transaction operation comes from service managing all DBs */
+ /** @var string Commit/rollback is from outside the IDatabase handle and connection manager */
+ const FLUSHING_ONE = '';
+ /** @var string Commit/rollback is from the connection manager for the IDatabase handle */
const FLUSHING_ALL_PEERS = 'flush';
- /** @var string Transaction operation comes from the database class internally */
+ /** @var string Commit/rollback is from the IDatabase handle internally */
const FLUSHING_INTERNAL = 'flush';
/** @var string Do not remember the prior flags */
const DBO_NOBUFFER = 2;
/** @var int Ignore query errors (internal use only!) */
const DBO_IGNORE = 4;
- /** @var int Autoatically start transaction on first query (work with ILoadBalancer rounds) */
+ /** @var int Automatically start a transaction before running a query if none is active */
const DBO_TRX = 8;
/** @var int Use DBO_TRX in non-CLI mode */
const DBO_DEFAULT = 16;
public function writesPending();
/**
- * Returns true if there is a transaction open with possible write
+ * Returns true if there is a transaction/round open with possible write
* queries or transaction pre-commit/idle callbacks waiting on it to finish.
* This does *not* count recurring callbacks, e.g. from setTransactionListener().
*
/**
* Run a callback as soon as there is no transaction pending.
* If there is a transaction and it is rolled back, then the callback is cancelled.
+ *
+ * When transaction round mode (DBO_TRX) is set, the callback will run at the end
+ * of the round, just after all peer transactions COMMIT. If the transaction round
+ * is rolled back, then the callback is cancelled.
+ *
* Queries in the function will run in AUTO-COMMIT mode unless there are begin() calls.
* Callbacks must commit any transactions that they begin.
*
* This is useful for updates to different systems or when separate transactions are needed.
* For example, one might want to enqueue jobs into a system outside the database, but only
* after the database is updated so that the jobs will see the data when they actually run.
- * It can also be used for updates that easily cause deadlocks if locks are held too long.
+ * It can also be used for updates that easily suffer from lock timeouts and deadlocks,
+ * but where atomicity is not essential.
*
* Updates will execute in the order they were enqueued.
*
/**
* Run a callback before the current transaction commits or now if there is none.
* If there is a transaction and it is rolled back, then the callback is cancelled.
+ *
+ * When transaction round mode (DBO_TRX) is set, the callback will run at the end
+ * of the round, just before all peer transactions COMMIT. If the transaction round
+ * is rolled back, then the callback is cancelled.
+ *
* Callbacks must not start nor commit any transactions. If no transaction is active,
* then a transaction will wrap the callback.
*
- * This is useful for updates that easily cause deadlocks if locks are held too long
+ * This is useful for updates that easily suffer from lock timeouts and deadlocks,
* but where atomicity is strongly desired for these updates and some related updates.
*
* Updates will execute in the order they were enqueued.
* @param string $fname
* @param string $cancelable Pass self::ATOMIC_CANCELABLE to use a
* savepoint and enable self::cancelAtomic() for this section.
+ * @return AtomicSectionIdentifier section ID token
* @throws DBError
*/
public function startAtomic( $fname = __METHOD__, $cancelable = self::ATOMIC_NOT_CANCELABLE );
* @since 1.31
* @see IDatabase::startAtomic
* @param string $fname
+ * @param AtomicSectionIdentifier $sectionId Section ID from startAtomic();
+ * passing this enables cancellation of unclosed nested sections [optional]
* @throws DBError
*/
- public function cancelAtomic( $fname = __METHOD__ );
+ public function cancelAtomic( $fname = __METHOD__, AtomicSectionIdentifier $sectionId = null );
/**
* Run a callback to do an atomic set of updates for this database
*
* @param string $fname Caller name (usually __METHOD__)
* @param callable $callback Callback that issues DB updates
+ * @param string $cancelable Pass self::ATOMIC_CANCELABLE to use a
+ * savepoint and enable self::cancelAtomic() for this section.
* @return mixed $res Result of the callback (since 1.28)
* @throws DBError
* @throws RuntimeException
* cancelAtomic(), and assumed no callers up the stack would ever try to
* catch the exception.
*/
- public function doAtomicSection( $fname, callable $callback );
+ public function doAtomicSection(
+ $fname, callable $callback, $cancelable = self::ATOMIC_NOT_CANCELABLE
+ );
/**
* Begin a transaction. If a transaction is already in progress,