DBI does not define what happens wrt transactions when disconnect is called.

Up to DBD::ODBC 1.29, DBD::ODBC always called SQLEndTran(SQL_ROLLBACK) to roll 
back any outstanding transactions (if AutoCommit was off) before calling 
SQLDisconnect. This means the outstanding transaction that is rolled back is 
hidden and that there is a difference between:

my $h = DBI->connect("dbi:ODBC:test","test","test", {AutoCommit => 0, 
RaiseError=>1, PrintWarn => 1});
$h->do(q/insert into mje values(?, ?)/, undef, 1, "fred");
# disconnect not called

and

my $h = DBI->connect("dbi:ODBC:test","test","test", {AutoCommit => 0, 
RaiseError=>1, PrintWarn => 1});
$h->do(q/insert into mje values(?, ?)/, undef, 1, "fred");
$h->disconnect or die $DBI::errstr;

because in the first case DBI catches the possible outstanding txn in DESTROY 
and issues:

Issuing rollback() due to DESTROY without explicit disconnect() of 
DBD::ODBC::db handle test.

but in the second case DBD::ODBC will rollback the transaction before 
disconnecting and there is no error or warning.

I don't really like this behaviour and would like to change it so in the second 
case above, DBD::ODBC issues a warning before rolling the txn back so you'd get 
something like:

DBD::ODBC::db disconnect warning: Disconnect with transaction in progress - 
rolling back

Obviously if you have PrintWarn turned off or are not using warnings it won't 
make any difference to you. Anyone have any fundamental objections to this 
change.

Martin
--
Martin J. Evans
Easysoft Limited
http://www.easysoft.com

Reply via email to