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