Todo tests for txn_rollback and scope_guard
[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
27   $DB::single = 1;
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 1;
43
44 __END__
45
46 =head1 NAME
47
48 DBIx::Class::Storage::TxnScopeGuard
49
50 =head1 SYNOPSIS
51
52  sub foo {
53    my ($self, $schema) = @_;
54
55    my $guard = $schema->txn_scope_guard;
56
57    # Multiple database operations here
58
59    $guard->commit;
60  }
61
62 =head1 DESCRIPTION
63
64 An object that behaves much like L<Scope::Guard>, but hardcoded to do the
65 right thing with transactions in DBIx::Class. 
66
67 =head1 METHODS
68
69 =head2 new
70
71 Creating an instance of this class will start a new transaction. Expects a
72 L<DBIx::Class::Storage> object as its only argument.
73
74 =head2 commit
75
76 Commit the transaction, and stop guarding the scope. If this method is not
77 called (i.e. an exception is thrown) and this object goes out of scope then
78 the transaction is rolled back.
79
80 =cut
81
82 =head1 SEE ALSO
83
84 L<DBIx::Class::Schema/txn_scope_guard>.
85
86 =head1 AUTHOR
87
88 Ash Berlin, 2008.
89
90 Insipred by L<Scope::Guard> by chocolateboy.
91
92 This module is free software. It may be used, redistributed and/or modified
93 under the same terms as Perl itself.
94
95 =cut