| DBIx::Transaction::db - Database handle that is aware of nested transactions | 
DBIx::Transaction::db - Database handle that is aware of nested transactions
See the DBIx::Transaction manpage
When you connect to a database using DBIx::Transaction, your database handle
will be a DBIx::Transaction::db object. These objects keep track of your
transaction state, allowing for transactions to occur within transactions,
and only sending ``commit'' or ``rollback'' instructions to the underlying
database when the outermost transaction has completed. See the DBIx::Transaction manpage
for a more complete explanation.
The following methods are overridden by DBIx::Transaction::db:
If there are no transactions currently running, begin_work will check
if AutoCommit is enabled. If it is enabled, a begin_work instruction
is sent to the underlying database layer. If AutoCommit is disabled, we
assume that the database has already started a transaction for us, and do
nothing. This means that you must always use begin_work to start a
transaction, even if AutoCommit is enabled!
If there is a transaction started, begin_work simply records that a nested
transaction has started.
begin_work returns the result of the database's begin_work call if it
makes one; otherwise it always returns true.
If there are no sub-transactions currently running, rollback will issue the
rollback call to the underlying database layer.
If there are sub-transactions currently running, rollback notes that the
nested transaction has been aborted.
If there is no transaction running at all, rollback will raise a fatal
error.
commit records that this
transaction has completed successfully and does nothing to the underlying
database layer.
If there are no sub-transactions currently running, commit checks if
there have been any transaction errors. If there has been a transaction
error, commit raises an exception. Otherwise, a commit call is
issued to the underlying database layer.
If there is no transaction running at all, commit will raise a fatal
error. This error will contain a full stack trace, and should also contain
the file names and line numbers where any rollbacks or query failures
happened.
commit
for the current transaction.
The following method is provided for convienence in setting up database transactions:
transaction($coderef)$coderef within a transaction.
$coderef is expected to return a scalar value.
If $coderef returns true, the transaction is committed. If
$coderef returns false or raises a fatal error, the transaction
is rolled back. The return value is the same as what is returned by
$coderef.
This method is supplied to make it easier to create nested transactions out of many small transactions. Example:
  sub get_max_id {
    my $dbh = shift;
    # this will roll back if it can't get MAX(num)
    $dbh->transaction(sub {
      if(my($id) = $dbh->selectrow_array("SELECT MAX(num) FROM foo")) {
        return $id;
      } else {
        return;
      }
    });
  }
  
  sub do_something {
    my($dbh, $num) = @_;
    $dbh->transaction(sub {
      $dbh->do("UPDATE foo SET bar = bar + 1 WHERE num = $num");
    });
  }
  
  sub do_many_things {
    my $dbh = shift;
    # if any of these sub-transactions roll back, the whole thing will roll
    # back
    $dbh->transaction(sub {
      if(
        do_something($dbh, 1) &&
        do_something($dbh, 2) &&
        (my $id = get_max_id($dbh))
      ) {
        return do_something($dbh, $id);
      } else {
        return;
      }
    });
  }
The following methods are used by the overridden methods. In most cases you won't have to use them yourself.
$dbh->rollback while $dbh->transaction_level;
But I would suggest that you structure your code so that each transaction and sub-transaction bails out safely instead, as that's a lot easier to trace and debug with confidence.
transaction_level by one. This is used by the begin_work override
and should not be called directly.
transaction_level by one. If this results in a negative number
(meaning more transactions have been commited/rolled back than started),
dec_transaction_level throws a fatal error. This is used by the
commit and rollback methods and should not be called directly.
rollback.
Optional parameters are the package, filename, and line where
the transaction error occured. If provided, they will be used in
error messages relating to the rollback.
rollback, and cleared whenever the
outermost transaction issues a rollback.
close_transaction($method)$method
(``commit'' or ``rollback'') on the underlying database layer and
resetting the DBIx::Transaction state. This method is used by the
commit and rollback methods and you shouldn't need to use it yourself,
unless you wanted to forcibly bail out of an entire transaction without
calling rollback repeatedly, but as stated above, that's a bad idea,
isn't it?
the DBI manpage, the DBIx::Transaction manpage
Tyler ``Crackerjack'' MacDonald <japh@crackerjack.net>
Copyright 2005 Tyler MacDonald This is free software; you may redistribute it under the same terms as perl itself.
| DBIx::Transaction::db - Database handle that is aware of nested transactions |