NAME
DBI::Transaction - advanced object-oriented support for database transactions
DOCUMENTATION STATE
Docs are incomplete and wrong!
PURPOSE
DBI::Transaction allows several transactions to be embedded inside each other (but see CAVEATS about problems with rolling back).
This is inevitable for modular development to allow modules automatically utilize transactions.
SYNOPSIS
use DBI::Transaction;
$transaction = DBI::Transaction->new($dbh);
# ...
$transaction->commit;
# or
$transaction->rollback; # See below for caveats.
CAVEATS
See below about destroying.
When several transactions are embedded in each other, attempt to rollback an inner transaction may throw an CannotRollback.
In this case you should rollback the entire upper level transaction.
At least in MySQL (DBD::mysql(3)) driver, connectiong with AutoCommit=>1 causes this module to commit three times rather than once! This is a bug in DBD::mysql(3). So use AutoCommit=>0 and manually commit the uttermost transaction:
$transaction = DBI::Transaction->new($dbh); # ... $transaction->commit; $dbh->commit;
$dbh->commit should not be called if was rollback CannotRollback... XXX. So, upper level transaction should be handled so (in MySQL):
$transaction = DBI::Transaction->new($dbh); # ... $transaction->commit; $dbh->disconnect;
When a library routine may call rollback() method from this class, this routine documentation should document that it calls it. The caller must trap the DBI::Transaction::CannotRollback, and (usually) roll back parent transactions in response on this CannotRollback.
DESTROYING
A transaction must be explicitly either commited or rolled back. Otherwise destroying it will throw an CannotRollback (see below).
Destroying a not finished transaction is considered as an error (TODO: Shouldn't we make it fatal?) and it meant only for debugging.
Destroying a not finished transaction attempts to roll back it before throwing the CannotRollback. But roll back may fail for the case of a subtransaction. (This useally signifies the need to roll back its parent transaction.)
DESCRIPTION
See DBI(3) for descriptions of database handles ($dbh).
- DBI::Transaction->new()
-
$transaction = DBI::Transaction->new($dbh);
This starts a transaction.
- commit()
-
Commits and finishes the transaction. Returns true on success.
- rollback()
-
Rolls back and finishes the transaction. Returns true on success.
- is_finished()
-
Returns false after commit or rollback,
- DBI::Transaction::CannotRollback
-
Exception for rolling back a transaction failed because it was a subtransaction of an other transaction.
RATIONALE
This module may seem to be over-sophisticated as we can use just
local $dbh->{AutoCommit} = 0;
But because of DBI(3) design deficiencies, we really need this module and it cannot be made simpler than it is without making it broken (at least without changing DBI(3) itself).
SUGGESTIONS
DESTROY of not finished transaction is only a debugging mean. You should not rely on its behavior.
If some routine may call $transaction->rollback() you should wrap this routine with "eval" unless it is the uttermost level transaction.
TODO
Docs are incomplete.
"Rollback to savepoint" feature of some SQL engines (e.g. MySQL) is not utilized.
AUTHOR
The original author Victor Porton <porton@ex-code.com> will gladly hear your bug reports.
Module's homepage: http://ex-code.com/dbi-transactions/
LICENSE
General Public License version 2 (see also module's homepage).