Added Bruno Vecchi to the Contributors section in DBIx/Class.pm
[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/;
1bc193ac 6
7sub new {
8 my ($class, $storage) = @_;
9
10 $storage->txn_begin;
11 bless [ 0, $storage ], ref $class || $class;
12}
13
14sub commit {
15 my $self = shift;
16
17 $self->[1]->txn_commit;
18 $self->[0] = 1;
19}
20
21sub DESTROY {
22 my ($dismiss, $storage) = @{$_[0]};
23
3b7f3eac 24 return if $dismiss;
25
26 my $exception = $@;
c6e27318 27
771298cf 28 carp 'A DBIx::Class::Storage::TxnScopeGuard went out of scope without explicit commit or error. Rolling back.'
d7ded411 29 unless $exception;
30
31 my $rollback_exception;
a778f387 32 {
33 local $@;
34 eval { $storage->txn_rollback };
d7ded411 35 $rollback_exception = $@;
36 }
c6e27318 37
d7ded411 38 if ($rollback_exception && $rollback_exception !~ /DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION/) {
c6e27318 39 if ($exception) {
40 $@ = "Transaction aborted: ${exception} "
41 ."Rollback failed: ${rollback_exception}";
42 }
43 else {
771298cf 44 # throws an object (verified with eval{}) but DESTROY eats the exception
45 $storage->throw_exception ("Rollback failed: ${rollback_exception}");
c6e27318 46 }
3b7f3eac 47 }
1bc193ac 48}
49
501;
51
52__END__
53
54=head1 NAME
55
6936e902 56DBIx::Class::Storage::TxnScopeGuard - Scope-based transaction handling
1bc193ac 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
72An object that behaves much like L<Scope::Guard>, but hardcoded to do the
73right thing with transactions in DBIx::Class.
74
75=head1 METHODS
76
77=head2 new
78
6936e902 79Creating an instance of this class will start a new transaction (by
80implicitly calling L<DBIx::Class::Storage/txn_begin>. Expects a
1bc193ac 81L<DBIx::Class::Storage> object as its only argument.
82
83=head2 commit
84
85Commit the transaction, and stop guarding the scope. If this method is not
6936e902 86called and this object goes out of scope (i.e. an exception is thrown) then
87the transaction is rolled back, via L<DBIx::Class::Storage/txn_rollback>
1bc193ac 88
89=cut
90
91=head1 SEE ALSO
92
93L<DBIx::Class::Schema/txn_scope_guard>.
94
95=head1 AUTHOR
96
97Ash Berlin, 2008.
98
99Insipred by L<Scope::Guard> by chocolateboy.
100
101This module is free software. It may be used, redistributed and/or modified
102under the same terms as Perl itself.
103
104=cut