SQLite Forum

ROLLBACK TO and AUTOCOMMIT flag
Login

ROLLBACK TO and AUTOCOMMIT flag

(1) By davorj on 2023-03-05 21:37:05 [link] [source]

Sqlite works in AUTOCOMMIT mode by default.

Would it make sense to extend ROLLBACK TO statement with ROLLBACK TO [...] AUTOCOMMIT, such that if the rollbacked-to-savepoint is the outer savepoint, then ROLLBACK TO [...] AUTOCOMMIT functions just like ROLLBACK, i.e. stopping the transaction and setting the AUTOCOMMIT flag to its prior state?

Why should this be interesting? Because ROLLBACK TO currently always leaves the transaction open. Now, a common programming pattern could be to place SAVEPOINT X; and then on error do something like: ROLLBACK TO X AUTOCOMMIT; within a function. Then this function can be used on its own, or within an other function that encapsulates it within a larger transaction. The issue with the current implementation from this former scenario, is that ROLLBACK TO always leaves the transaction open, so the function, when executed on its own, may break subsequent code that assumes AUTOCOMMIT is ON. For example, the subsequent code may have a SELECT statement which would set a SHARED LOCK on the DB due to open transaction, not allowing other concurrent processes to start their own transactions.

Hence adding the argument "AUTOCOMMIT" to ROLLBACK TO statement would be an elegant solution, unless I am ignorant of something else?

(2) By Keith Medcalf (kmedcalf) on 2023-03-06 00:38:35 in reply to 1 [link] [source]

Why not just release the savepoint if you created it, before you are finished with whatever step you are doing? That is, if you created the savepoint, then release it when you are done with it.

So in the function you:

  1. create the savepoint
  2. do your stuff
  3. if there was an error rolback the savepoint
  4. release the savepoint
  5. return whether an error occurred or not

It would probably be better use proper design in the first place than to add crutches to a crippled design.

(3) By Donal Fellows (dkfellows) on 2023-03-06 09:13:07 in reply to 1 [link] [source]

the subsequent code may have a SELECT statement which would set a SHARED LOCK on the DB due to open transaction

Presumably it would be doing so because it is actually important for the SELECT to be done within the explicit transaction. Knowing where the transaction boundaries are is rather important in pretty much all non-trivial uses of databases, especially if there are concurrent uses.

If you'd been arguing for a ROLLBACK TO AND RELEASE semantics that would have made some sense (that is, it would move the transaction log being built to the moment before the SAVEPOINT was made, not the moment after as now) but it's totally out of order to presume that that means that you'd be going into AUTOCOMMIT mode; that would depend on context. As it is, you have an easy solution: add a separate RELEASE and, because it's still within a transaction, that won't be subject to weird concurrency issues.

The documentation clearly describes what the abstract semantics of savepoints are. Specifically:

One can also think of savepoints as "marks" in the transaction timeline. In this view, the SAVEPOINT command creates a new mark, the ROLLBACK TO command rewinds the timeline back to a point just after the named mark, and the RELEASE command erases marks from the timeline without actually making any changes to the database.

(4) By davorj on 2023-03-06 17:15:34 in reply to 3 [source]

If you'd been arguing for a ROLLBACK TO AND RELEASE semantics that would have made some sense (that is, it would move the transaction log being built to the moment before the SAVEPOINT was made, not the moment after as now) [...]

Your technical explanation with the transaction log is spot on, and that is indeed what I was trying to explain.

And indeed, adding a separate RELEASE after ROLLBACK TO is equivalent. I just see that now.

Thanks for the tip, Donal! Excellent answer, solution and suggestion for a future addition!