Louis Erickson wrote:
On Thu, 14 May 2009, Chris Cole wrote:
<snip>
Why does it work fine when I have Autocommit 'on', but get the following
error with Autocommit 'off':
I'm surprised no one else has replied.
I must have missed the message.
This bit me too when I first
started with DBIC. It seemed backwards to me at the time.
I started trying to modify it ot make it proper before reading the docs
fully.
DBIx::Class assumes autocommit is on, and works strangely or not at all if
it is off.
Its actually programmed "if autocommit is off, do not issue begin,
commit, or rollback instructions". Which blew my mind and had me
ranting wtfwtfwtf for a good hour. I couldn't believe that it would be
so very backwards in such well-executed and known code.
If you must have it off, say, to share a db handle with older code that
requires it, you can usually finesse it to work but transactions will be
hard. The one time I found myself in that situation, I discovered opening
a second handle was easier.
You'll be best off with DBIC to leave autocommit on and use DBIC's
transaction handling through txn_do instead. It works well and handles
some things the raw DBI one won't.
I should tell you of my approach to this interesting problem, in which I
solve the dilemma of 'was a previous modifier command issued' AND leave
autocommit off.
I turned on autocommit initially becuase I wanted to enforce the
application rules like this:
1. All modifications to the database shall occur in a dbic transaction.
2. If its not in a transaction, it didn't happen, and it will be rolled
back with prejudice.
Imagine my frustration when I tried to impliment it and the system
refused to issue transaction commands entirely!
Since as the documentation says, with autocommit off the library cannot
trust that you didn't already do something, thus we cannot trust the DB
transaction, I created a new method to call called
'trust_dbic_transactions'. I augmented a local copy of the DBIx::Class
file in question that now operates as I wish it to. (A Rollback is
issued before every txn_do after called). By setting this parameter I
clearly state, if you say you trust, any modification done outside of a
transaction IS WRONG, and gets rolled back, no questions asked.
So far its found a whole passel of bugs and deviations from application
pattern that would not otherwise obvious - because you tell it to make a
change and the change never happens! I like this enforcement feature,
and think my application is the better for it.
Maybe I should submit it as a patch to DBIx::Class - Sometimes for code
quality reasons you actually DO want to trust dbic transactions, even
though you've turned off autocommit. (Because if autocommit is on, your
application transaction layer loses control and a spurious modification
sql can throw the db into a wrong state). This is all part of the
paradigm of making potential problems noisy. Throw early, throw often,
make it clear when something is not following the rules as soon as it is
possible to tell.
David
_______________________________________________
List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
Searchable Archive: http://www.grokbase.com/group/[email protected]