::Replicated - test hashref for connect_replicants and croak on coderef, switch to...
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Storage / TxnScopeGuard.pm
1 package DBIx::Class::Storage::TxnScopeGuard;
2
3 use strict;
4 use warnings;
5
6 sub new {
7   my ($class, $storage) = @_;
8
9   $storage->txn_begin;
10   bless [ 0, $storage ], ref $class || $class;
11 }
12
13 sub commit {
14   my $self = shift;
15
16   $self->[1]->txn_commit;
17   $self->[0] = 1;
18 }
19
20 sub DESTROY {
21   my ($dismiss, $storage) = @{$_[0]};
22
23   return if $dismiss;
24
25   my $exception = $@;
26   Carp::cluck("A DBIx::Class::Storage::TxnScopeGuard went out of scope without explicit commit or an error - bad")
27     unless $exception; 
28   {
29     local $@;
30     eval { $storage->txn_rollback };
31     my $rollback_exception = $@;
32     if($rollback_exception) {
33       my $exception_class = "DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION";
34
35       $storage->throw_exception(
36         "Transaction aborted: ${exception}. "
37         . "Rollback failed: ${rollback_exception}"
38       ) unless $rollback_exception =~ /$exception_class/;
39     }
40   }
41 }
42
43 1;
44
45 __END__
46
47 =head1 NAME
48
49 DBIx::Class::Storage::TxnScopeGuard - Scope-based transaction handling
50
51 =head1 SYNOPSIS
52
53  sub foo {
54    my ($self, $schema) = @_;
55
56    my $guard = $schema->txn_scope_guard;
57
58    # Multiple database operations here
59
60    $guard->commit;
61  }
62
63 =head1 DESCRIPTION
64
65 An object that behaves much like L<Scope::Guard>, but hardcoded to do the
66 right thing with transactions in DBIx::Class. 
67
68 =head1 METHODS
69
70 =head2 new
71
72 Creating an instance of this class will start a new transaction (by
73 implicitly calling L<DBIx::Class::Storage/txn_begin>. Expects a
74 L<DBIx::Class::Storage> object as its only argument.
75
76 =head2 commit
77
78 Commit the transaction, and stop guarding the scope. If this method is not
79 called and this object goes out of scope (i.e. an exception is thrown) then
80 the transaction is rolled back, via L<DBIx::Class::Storage/txn_rollback>
81
82 =cut
83
84 =head1 SEE ALSO
85
86 L<DBIx::Class::Schema/txn_scope_guard>.
87
88 =head1 AUTHOR
89
90 Ash Berlin, 2008.
91
92 Insipred by L<Scope::Guard> by chocolateboy.
93
94 This module is free software. It may be used, redistributed and/or modified
95 under the same terms as Perl itself.
96
97 =cut