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