- Issue created by @mondrake
Follow-up to #3407080-8: Leaving the savepoint in the transaction stack upon rollback is incorrect → .
TransactionManager
implements strict LIFO for rollback, i.e. you can only rollback to latest active savepoint.
From https://git.drupalcode.org/project/drupal/-/blob/11.x/core/lib/Drupal/Co... :
/**
* The stack of Drupal transactions currently active.
*
* This property is keeping track of the Transaction objects started and
* ended as a LIFO (Last In, First Out) stack.
*
* The database API allows to begin transactions, add an arbitrary number of
* additional savepoints, and release any savepoint in the sequence. When
* this happens, the database will implicitly release all the savepoints
* created after the one released. Given Drupal implementation of the
* Transaction objects, we cannot force descoping of the corresponding
* Transaction savepoint objects from the manager, because they live in the
* scope of the calling code. This stack ensures that when an outlived
* Transaction object gets out of scope, it will not try to release on the
* database a savepoint that no longer exists.
*
* Differently, rollbacks are strictly being checked for LIFO order: if a
* rollback is requested against a savepoint that is not the last created,
* the manager will throw a TransactionOutOfOrderException.
*
* The array key is the transaction's unique id, its value a StackItem.
*
* @var array<string,StackItem>
*/
As noted in the parent, this behaviour could be loosened to allow rolling back to any savepoint/root at discretion.