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 )