use namespace::clean w/ Try::Tiny
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Storage / TxnScopeGuard.pm
CommitLineData
6936e902 1package DBIx::Class::Storage::TxnScopeGuard;
1bc193ac 2
3use strict;
4use warnings;
c6e27318 5use Carp::Clan qw/^DBIx::Class/;
ed7ab0f4 6use Try::Tiny;
fd323bf1 7use namespace::clean;
1bc193ac 8
9sub new {
10 my ($class, $storage) = @_;
11
12 $storage->txn_begin;
13 bless [ 0, $storage ], ref $class || $class;
14}
15
16sub commit {
17 my $self = shift;
18
19 $self->[1]->txn_commit;
20 $self->[0] = 1;
21}
22
23sub DESTROY {
24 my ($dismiss, $storage) = @{$_[0]};
25
3b7f3eac 26 return if $dismiss;
27
28 my $exception = $@;
c6e27318 29
a778f387 30 {
31 local $@;
36099e8c 32
33 carp 'A DBIx::Class::Storage::TxnScopeGuard went out of scope without explicit commit or error. Rolling back.'
34 unless $exception;
35
ed7ab0f4 36 my $rollback_exception;
37 try { $storage->txn_rollback }
38 catch { $rollback_exception = shift };
c6e27318 39
ed7ab0f4 40 if (defined $rollback_exception && $rollback_exception !~ /DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION/) {
36099e8c 41 if ($exception) {
42 $exception = "Transaction aborted: ${exception} "
c6e27318 43 ."Rollback failed: ${rollback_exception}";
36099e8c 44 }
45 else {
46 carp (join ' ',
47 "********************* ROLLBACK FAILED!!! ********************",
48 "\nA rollback operation failed after the guard went out of scope.",
49 'This is potentially a disastrous situation, check your data for',
50 "consistency: $rollback_exception"
51 );
52 }
c6e27318 53 }
3b7f3eac 54 }
36099e8c 55
56 $@ = $exception;
1bc193ac 57}
58
591;
60
61__END__
62
63=head1 NAME
64
6936e902 65DBIx::Class::Storage::TxnScopeGuard - Scope-based transaction handling
1bc193ac 66
67=head1 SYNOPSIS
68
69 sub foo {
70 my ($self, $schema) = @_;
71
72 my $guard = $schema->txn_scope_guard;
73
74 # Multiple database operations here
75
76 $guard->commit;
77 }
78
79=head1 DESCRIPTION
80
81An object that behaves much like L<Scope::Guard>, but hardcoded to do the
fd323bf1 82right thing with transactions in DBIx::Class.
1bc193ac 83
84=head1 METHODS
85
86=head2 new
87
6936e902 88Creating an instance of this class will start a new transaction (by
89implicitly calling L<DBIx::Class::Storage/txn_begin>. Expects a
1bc193ac 90L<DBIx::Class::Storage> object as its only argument.
91
92=head2 commit
93
94Commit the transaction, and stop guarding the scope. If this method is not
48580715 95called and this object goes out of scope (e.g. an exception is thrown) then
6936e902 96the transaction is rolled back, via L<DBIx::Class::Storage/txn_rollback>
1bc193ac 97
98=cut
99
100=head1 SEE ALSO
101
102L<DBIx::Class::Schema/txn_scope_guard>.
103
104=head1 AUTHOR
105
106Ash Berlin, 2008.
107
48580715 108Inspired by L<Scope::Guard> by chocolateboy.
1bc193ac 109
110This module is free software. It may be used, redistributed and/or modified
111under the same terms as Perl itself.
112
113=cut