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);