DBIx-QuickORM
view release on metacpan or search on metacpan
lib/DBIx/QuickORM/Manual/Transactions.pm view on Meta::CPAN
package DBIx::QuickORM::Manual::Transactions;
use strict;
use warnings;
our $VERSION = '0.000022';
1;
__END__
=head1 NAME
DBIx::QuickORM::Manual::Transactions - A guide to transactions in
L<DBIx::QuickORM>.
=head1 DESCRIPTION
This guide covers transactions in L<DBIx::QuickORM>: starting a transaction,
nesting transactions as savepoints, queuing success / fail / completion
callbacks, controlling a transaction by hand, and automatically retrying work
when a connection is lost.
Transactions are controlled through the connection
(L<DBIx::QuickORM::Connection>). Each transaction or savepoint is represented
by a L<DBIx::QuickORM::Connection::Transaction> object.
This is part of the L<DBIx::QuickORM> documentation; see
L<DBIx::QuickORM::Manual> for the documentation hub.
=head1 BASIC TRANSACTIONS
The simplest way to run a transaction is to pass an action callback to
C<txn()> on the connection:
$con->txn(sub {
my $txn = shift;
$foo->update(...);
$bar->insert(...);
});
If the callback returns normally the transaction is committed. If it throws an
exception, the transaction is rolled back and the exception propagates.
C<transaction()> is a full alias for C<txn()>; use whichever reads better.
C<txn()> always returns a L<DBIx::QuickORM::Connection::Transaction> object.
When you pass an action callback the returned object is already complete, so
you can inspect its outcome (see L</"THE TRANSACTION OBJECT"> below).
=head2 MANUAL CONTROL FROM INSIDE THE CALLBACK
The callback receives the transaction object as its only argument. You can end
the transaction early by calling C<commit> or C<rollback> on it; either one
breaks out of the action callback:
$con->txn(sub {
my $txn = shift;
...
$txn->rollback if $should_abort; # exits the callback, rolls back
...
$txn->commit("looks good"); # exits the callback, commits
});
C<abort> is an alias for C<rollback>. Both C<commit> and C<rollback> accept an
optional reason string.
=head1 NESTED TRANSACTIONS AND SAVEPOINTS
Calls to C<txn()> may be nested. The outermost call starts a real database
transaction; each nested call creates a savepoint instead. Committing an inner
transaction releases its savepoint; rolling one back rolls back to its
savepoint without disturbing the outer transaction.
$con->txn(sub { # real transaction
$foo->insert(...);
$con->txn(sub { # savepoint
$bar->insert(...);
# rolling this back undoes only $bar's insert
});
$baz->insert(...);
}); # commit happens here
Use C<is_savepoint> on a transaction object to tell which kind it is.
=head1 CALLBACKS
You can queue callbacks to run when a transaction finishes. They are fired
after the underlying commit or rollback has been issued.
=over 4
=item on_success
Runs only if the transaction commits.
=item on_fail
Runs only if the transaction is rolled back.
=item on_completion
Runs when the transaction finishes, regardless of outcome.
=back
Pass them as parameters to C<txn()>:
$con->txn(
on_success => sub { my $txn = shift; ... },
on_fail => sub { my $txn = shift; ... },
on_completion => sub { my $txn = shift; ... },
action => sub { my $txn = shift; ... },
);
You can also queue callbacks against an existing transaction object directly
with C<add_success_callback>, C<add_fail_callback>, and
C<add_completion_callback>.
=head2 PARENT AND ROOT CALLBACKS
When you are inside a nested transaction you can attach callbacks to an outer
transaction instead of the current one. This is useful when a savepoint wants
to defer work until the enclosing transaction actually commits.
The C<on_parent_*> variants attach to the immediate parent transaction; the
C<on_root_*> variants attach to the outermost (root) transaction no matter how
deeply nested you are:
$con->txn(
on_parent_success => sub { ... },
on_parent_fail => sub { ... },
on_parent_completion => sub { ... },
on_root_success => sub { ... },
on_root_fail => sub { ... },
on_root_completion => sub { ... },
action => sub { ... },
);
When there is no parent or root transaction above the current one, the
corresponding parent / root callbacks are simply no-ops.
=head1 LONG-LIVED TRANSACTIONS
If you need a transaction that is not bound to a single callback, call C<txn()>
without an action. It returns a live L<DBIx::QuickORM::Connection::Transaction>
object that you control by hand:
my $txn = $con->txn();
...
$txn->commit; # or $txn->rollback;
If the transaction object falls completely out of scope and is destroyed while
still open, it is rolled back automatically as a safety net. Never rely on this
for normal flow; commit or roll back explicitly.
=head1 THE TRANSACTION OBJECT
A L<DBIx::QuickORM::Connection::Transaction> exposes its state:
=over 4
=item $txn->state
Returns one of C<active>, C<committed>, or C<rolled_back>. Derived from
C<result>.
=item $txn->committed
=item $txn->rolled_back
True/false/undef booleans derived from C<result>: C<committed> is true after a
successful commit, C<rolled_back> is its inverse, and both return undef while
the transaction is still open.
=item $txn->exception
The exception that forced a rollback, if any. Set when the transaction body
threw or the object fell out of scope; undef for a normal commit or an explicit
C<rollback>.
=item $txn->is_savepoint
True when this transaction is a savepoint (i.e. it was nested inside another
transaction).
=item $txn->result
Undef while the transaction is still open; C<1> after a successful commit, C<0>
after a rollback.
=back
See L<DBIx::QuickORM::Connection::Transaction> for the full interface.
=head1 INSPECTING THE CURRENT TRANSACTION
The connection can tell you whether a transaction is active:
=over 4
( run in 0.573 second using v1.01-cache-2.11-cpan-5b529ec07f3 )