gam3 has asked for the wisdom of the Perl Monks concerning the following question:

I would like to be able to test if I forgot to issue a $dbh->commit. I suppose that I could disconnect and reconnect and test data, but it seems to me that DBI may have a flag available to tell me if it will rollback when I call $dbh->disconnect(), or there may be someother way to do this that I have not thought of.

Allen

-- gam3
A picture is worth a thousand words, but takes 200K.

Replies are listed 'Best First'.
Re: Testing if DBI has a commit pending?
by ptum (Priest) on Sep 19, 2006 at 14:49 UTC

    There is always the Executed flag in DBI:

    Executed (boolean)

    The Executed attribute is true if the handle object has been "executed". Currently only the $dbh do() method and the $sth execute(), execute_array(), and execute_for_fetch() methods set the Executed attribute.

    When it's set on a handle it is also set on the parent handle at the same time. So calling execute() on a $sth also sets the Executed attribute on the parent $dbh.

    The Executed attribute for a database handle is cleared by the commit() and rollback() methods. The Executed attribute of a statement handle is not cleared by the DBI under any circumstances and so acts as a permanent record of whether the statement handle was ever used.

    The Executed attribute was added in DBI 1.41.

    Update: I must admit to some curiousity, as to why you might need this functionality. I generally rely on the AUTOCOMMIT flag, and rollback as necessary, in the rare occasions when I have multi-stage transactions that go bad. Can you comment on your use case?

      I have a update that is followed by an insert and if the insert fails I need the update to fail. I can't have the insert before the update because it would violate a business rule (unique index). It is very unlike that the insert will fail, but if it does the database will be left in a state that should be impossible.

      I can think of lots of times when commit/rollback is needed to keep a database consistent. Though the INSERT ... ON DUPLICATE KEY functionality has reduced the number of those cases.

      -- gam3
      A picture is worth a thousand words, but takes 200K.

        This is exactly what commit is for though. Issue your update, issue your insert. If the insert fails the rollback, otherwise commit. I'm not sure how an insert before an update would cause such a business rule to fail, but if that is indeed the case then just rollback on failure. At that point you would then retry with a new update/insert/commit cycle.


        ___________
        Eric Hodges
Re: Testing if DBI has a commit pending?
by jasonk (Parson) on Sep 19, 2006 at 14:57 UTC

    Other than using the Executed attribute to determine whether 'something' has been done or not, I doubt you can get this information from DBI. DBI could tell you if a transaction was started, if commands were sent to the database server, and whether or not that transaction had been committed or rolled back, but the problem is that it couldn't reliably tell whether the commands that were sent to the database resulted in changes that need to be committed or not.

    Long story short, this isn't something you should be asking DBI, it's a question you would have to pose to your database, and how you find that information is going to be database dependent.


    We're not surrounded, we're in a target-rich environment!
Re: Testing if DBI has a commit pending?
by CountZero (Bishop) on Sep 19, 2006 at 20:52 UTC
    "Forgetting" is not something which rhymes with good programming practice. You just code in such a way that you test whether you have to rollback or not at the appropriate time.

    It is not as if half-way through the program the processor suddenly remembers that it should have checked for rollback, is it?

    CountZero

    "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law