On Sat, Dec 06, 2008 at 07:41:24AM -0800, Jonathan Leffler wrote:
> >
> > The situation doesn't come up frequently, so I am just wanting to find
> > out what DBI is going to do when it does. I checked the logs of the
> > program and for every delete that the program reports that it
> > attempted, those records are no longer present in the database. So I
> > am trying to get a clearer understanding of what is going on in this
> > case.
> 
> DBI disconnects.  What the DBMS does depends on the DBMS.
> 
> I believe Oracle commits; Informix definitely rolls back incomplete
> transactions.

For drivers using the Driver.xst 'driver interface template' (which
includes DBD::Oracle), rollback() is automatcally called just before the
handle is DESTROYd. I've appended the relevant code.

Tim.

        if (DBIc_ACTIVE(imp_dbh)) {
            if (!DBIc_has(imp_dbh,DBIcf_AutoCommit)) {
                /* Application is using transactions and hasn't explicitly 
disconnected.
                    Some databases will automatically commit on graceful 
disconnect.
                    Since we're about to gracefully disconnect as part of the 
DESTROY
                    we want to be sure we're not about to implicitly commit 
changes
                    that are incomplete and should be rolled back. (The DESTROY 
may
                    be due to a RaiseError, for example.) So we rollback here.
                    This will be harmless if the application has issued a 
commit,
                    XXX Could add an attribute flag to indicate that the driver
                    doesn't have this problem. Patches welcome.
                    XXX or could just move the DBIc_is(imp_dbh, DBIcf_Executed) 
test
                    to cover the rollback as well. That just needs sanity 
checking
                    that DBIcf_Executed is set by any/all possible way to 
execute a
                    statement that might start a transaction.
                */
                if (DBIc_WARN(imp_dbh)
                &&  DBIc_is(imp_dbh, DBIcf_Executed) /* has not just called 
commit/rollback */
                && (!dirty || DBIc_DBISTATE(imp_dbh)->debug >= 3)
                )
                     warn("Issuing rollback() for database handle being 
DESTROY'd without explicit disconnect()");
                dbd_db_rollback(dbh, imp_dbh);                  /* ROLLBACK! */
            }
            dbd_db_disconnect(dbh, imp_dbh);

Reply via email to