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