At 12:33 PM -0400 4/9/07, Igor Tandetnik wrote:
Dennis Cote <[EMAIL PROTECTED]> wrote:
Darren Duncan wrote:

I will clarify that child transactions are just an elegant way of
partitioning a larger task, and that parent transactions always
overrule children; even if a child transaction commits successfully,
a rollback of its parent means there are no lasting changes.

Because of this, and the fact that a transaction is basically a
guarantee that all or none of the enclosed statements are executed, it
is much simpler to implement nested transactions using a counter and
the existing transaction API in a set of wrapper functions. There is no
need to maintain all the intermediate state information.

Support for nested transactions should allow one to roll back the child transaction to the point where it has started, but still commit the overall transaction. Consider:

BEGIN parent;
insert into t values ('a');
BEGIN child;
insert into t values ('b');
ROLLBACK child;
insert into t values ('c');
COMMIT parent;

As a result of this sequence, the table should have two new rows with values 'a' and 'c', but not 'b'. As far as I can tell, this is impossible to implement in terms of existing SQLite API.

Yes, exactly.

The whole point of nested transactions is that if a child transaction fails, the state still retains all changes made prior to the child starting, and after its parent started. It is a lot less complicated, and particularly more reliable, for the DBMS itself to manage this.

Moreover, in the case of stored procedures like triggers where triggers have their own child transactions, the application doesn't even see control between different transaction levels.

The whole point of being implemented as separate transactions rather than "save points" is that any particular block of code or SQL that needs to be atomic doesn't have to special case how it is defined depending on whether it is a main or child transaction, and it doesn't matter how many parents it has ... just like a function invocation in a normal programming language doesn't have to know how high the call stack is.

Note that, if SQLite currently supports the ability to have an individual SQL statement fail and leave no lasting effects, without any non-nested transaction rolling back, then it is already partially supporting the nested transaction feature, such that there are up to 2 transaction levels, any explicit one, plus the implicit one that is SQL statement itself. So we just have to extend this to N levels.

Now, as far as user syntax goes ... considering my 3rd paragraph above, it is vital that the syntax for start/commit/rollback a child transaction is identical to invoking an initial/non-nested transaction ... so that users don't have to know whether they are nested or not.

-- Darren Duncan

-----------------------------------------------------------------------------
To unsubscribe, send email to [EMAIL PROTECTED]
-----------------------------------------------------------------------------

Reply via email to