[Dbix-class] ROLLBACK seems to be skipped on 0.08
Darren Duncan
darren at DarrenDuncan.net
Mon Oct 22 21:06:03 GMT 2007
At 2:08 PM -0500 10/22/07, Brandon Black wrote:
>On 10/22/07, Jesper Krogh <jesper at krogh.cc> wrote:
>> Brandon Black wrote:
>> > So I guess what I'm saying is that forcing AutoCommit=>0 users to use
>> > explicit txns everywhere isn't compatible with the idea of generic
>> > DBIC modules/plugins and the idea of allowing AutoCommit=>1 users to
>> > not wrap everything in txns.
>> >
>> > I'm still thinking...
>>
>> Would it be an option to clearly mark the $storage->txn_begin/commit
>> stuff as deprecated and make it work "as broken" as in 0.07?
>>
>
>Yes, I think, but it's more than just manual txn_begin/commit that are
>broken and should be deprecated...
>
>The 0.07 behavior under AutoCommit=>0 in general is broken too, and we
>shouldn't be aiming to go back to it. We should be looking for a
>long-term solution first, and then once we've got a workable long-term
>solution, we can examine what the best interim approach is to get us
>there that doesn't conflict and doesn't cause existing code more grief
>than necessary.
In case it would be helpful, I'll briefly describe the behaviour of
Muldis DB (whose language is Muldis D rather than SQL) with respect
to transactions.
If you end up adopting Muldis DB for a DBIx-Class Storage:: layer,
you would have to account for that in your own interface, or
alternately in just your implementation, since it would be no more
complex to emulate the current DBIx-Class behaviour over it relative
to the complexity of doing what you do now over DBI; but if your
interface is the same, that is less system complexity.
Or if you don't adopt Muldis DB, hopefully you will learn from this
design anyway.
Muldis DB's API is based on the concept of invoking stored routines,
via call_proc(), those routines being either/both system-defined or
user-defined. You should find it the simplest and most efficient to
use if you have, at least conceptually, wrapped your data
manipulation statements in stored procedures (that have 0..N
parameters) and those are part of your database schema, and your
application just invokes those rather than directly invoking
insert/update/delete.
By default, each variable update operation in Muldis DB is atomic,
including database variables; more specifically, every system-defined
routine that updates a variable is atomic, that is, an implicit
transaction. In SQL terms, this includes each insert/update/delete,
which are system-defined routines.
Muldis DB always works with a nested transaction paradigm, and each
system-defined routine call is an implicit child-most transaction of
any explicit parent transaction that there might be. If there is no
explicit parent transaction, then effectively the DBMS is operating
in auto-commit mode, save that each system routine call is atomic.
The only way to effectively turn off this auto-commit mode is to
explicitly define a transaction around, directly or indirectly,
multiple system routine calls.
Within Muldis D routines, all explicit transactions are specifically
tied to a particular lexical scope, and moreover these are tied to
the exception-based error handling system. If the lexical scope in
question ends normally, then its transaction commits; if it ends
early due to an exception, then its transaction rolls back. You
can't turn exceptions off but you can trap them.
Based on my understanding of DBIx-Class' txn_do(), using that is the
closest thing to (assuming autocommit=1), and/or identical to, how
Muldis DB works, and txn_do() is also the type of design I recommend.
Muldis DB also has separate start|commit|rollback_trans() methods
that the Perl application can invoke (but Muldis D stored routines
can't) whose purpose is to support wider-scope parent-most
transactions in the application where it isn't practical to put all
parts of it into a stored routine, such as because interaction with
non-database systems or users needs to be done between stages.
Based on my understanding, DBIx-Class' separate
txn_begin|commit|rollback() routines correspond to this, assuming
they aren't invoked by user code in a txn_do().
To summarize, I recommend for DBIx-Class an emphasis on txn_do() for
any situation where it would work, which includes executing just
single operations, and that autocommit=1 should be constant. An
autocommit=0 can be simulated by just having explicit
begin/commit/rollback where appropriate.
-- Darren Duncan
More information about the DBIx-Class
mailing list