This is how the txnguard should really work
[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
28 carp 'A DBIx::Class::Storage::TxnScopeGuard went out of scope without explicit commit or error - bad'
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 {
44 carp "Rollback failed: ${rollback_exception}";
45 }
3b7f3eac 46 }
1bc193ac 47}
48
491;
50
51__END__
52
53=head1 NAME
54
6936e902 55DBIx::Class::Storage::TxnScopeGuard - Scope-based transaction handling
1bc193ac 56
57=head1 SYNOPSIS
58
59 sub foo {
60 my ($self, $schema) = @_;
61
62 my $guard = $schema->txn_scope_guard;
63
64 # Multiple database operations here
65
66 $guard->commit;
67 }
68
69=head1 DESCRIPTION
70
71An object that behaves much like L<Scope::Guard>, but hardcoded to do the
72right thing with transactions in DBIx::Class.
73
74=head1 METHODS
75
76=head2 new
77
6936e902 78Creating an instance of this class will start a new transaction (by
79implicitly calling L<DBIx::Class::Storage/txn_begin>. Expects a
1bc193ac 80L<DBIx::Class::Storage> object as its only argument.
81
82=head2 commit
83
84Commit the transaction, and stop guarding the scope. If this method is not
6936e902 85called and this object goes out of scope (i.e. an exception is thrown) then
86the transaction is rolled back, via L<DBIx::Class::Storage/txn_rollback>
1bc193ac 87
88=cut
89
90=head1 SEE ALSO
91
92L<DBIx::Class::Schema/txn_scope_guard>.
93
94=head1 AUTHOR
95
96Ash Berlin, 2008.
97
98Insipred by L<Scope::Guard> by chocolateboy.
99
100This module is free software. It may be used, redistributed and/or modified
101under the same terms as Perl itself.
102
103=cut