Filename | /2home/ss5/perl5/perlbrew/perls/perl-5.12.3/lib/site_perl/5.12.3/DBIx/Class/Storage/TxnScopeGuard.pm |
Statements | Executed 5318 statements in 18.1ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
294 | 1 | 1 | 8.91ms | 71.5ms | new | DBIx::Class::Storage::TxnScopeGuard::
294 | 2 | 2 | 4.88ms | 4.88ms | DESTROY | DBIx::Class::Storage::TxnScopeGuard::
294 | 2 | 2 | 4.65ms | 34.9s | commit | DBIx::Class::Storage::TxnScopeGuard::
1 | 1 | 1 | 16µs | 16µs | BEGIN@7 | DBIx::Class::Storage::TxnScopeGuard::
1 | 1 | 1 | 12µs | 14µs | BEGIN@3 | DBIx::Class::Storage::TxnScopeGuard::
1 | 1 | 1 | 10µs | 46µs | BEGIN@5 | DBIx::Class::Storage::TxnScopeGuard::
1 | 1 | 1 | 7µs | 34µs | BEGIN@6 | DBIx::Class::Storage::TxnScopeGuard::
1 | 1 | 1 | 7µs | 238µs | BEGIN@10 | DBIx::Class::Storage::TxnScopeGuard::
1 | 1 | 1 | 7µs | 15µs | BEGIN@4 | DBIx::Class::Storage::TxnScopeGuard::
1 | 1 | 1 | 6µs | 6µs | BEGIN@8 | DBIx::Class::Storage::TxnScopeGuard::
1 | 1 | 1 | 6µs | 56µs | BEGIN@9 | DBIx::Class::Storage::TxnScopeGuard::
0 | 0 | 0 | 0s | 0s | __ANON__[:138] | DBIx::Class::Storage::TxnScopeGuard::
0 | 0 | 0 | 0s | 0s | __ANON__[:139] | DBIx::Class::Storage::TxnScopeGuard::
0 | 0 | 0 | 0s | 0s | __ANON__[:51] | DBIx::Class::Storage::TxnScopeGuard::
0 | 0 | 0 | 0s | 0s | __ANON__[:61] | DBIx::Class::Storage::TxnScopeGuard::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package DBIx::Class::Storage::TxnScopeGuard; | ||||
2 | |||||
3 | 3 | 17µs | 2 | 16µs | # spent 14µs (12+2) within DBIx::Class::Storage::TxnScopeGuard::BEGIN@3 which was called:
# once (12µs+2µs) by DBIx::Class::Storage::BEGIN@17 at line 3 # spent 14µs making 1 call to DBIx::Class::Storage::TxnScopeGuard::BEGIN@3
# spent 2µs making 1 call to strict::import |
4 | 3 | 20µs | 2 | 24µs | # spent 15µs (7+9) within DBIx::Class::Storage::TxnScopeGuard::BEGIN@4 which was called:
# once (7µs+9µs) by DBIx::Class::Storage::BEGIN@17 at line 4 # spent 15µs making 1 call to DBIx::Class::Storage::TxnScopeGuard::BEGIN@4
# spent 9µs making 1 call to warnings::import |
5 | 3 | 23µs | 2 | 81µs | # spent 46µs (10+36) within DBIx::Class::Storage::TxnScopeGuard::BEGIN@5 which was called:
# once (10µs+36µs) by DBIx::Class::Storage::BEGIN@17 at line 5 # spent 46µs making 1 call to DBIx::Class::Storage::TxnScopeGuard::BEGIN@5
# spent 36µs making 1 call to Exporter::import |
6 | 3 | 26µs | 2 | 60µs | # spent 34µs (7+27) within DBIx::Class::Storage::TxnScopeGuard::BEGIN@6 which was called:
# once (7µs+27µs) by DBIx::Class::Storage::BEGIN@17 at line 6 # spent 34µs making 1 call to DBIx::Class::Storage::TxnScopeGuard::BEGIN@6
# spent 27µs making 1 call to Exporter::import |
7 | 3 | 29µs | 1 | 16µs | # spent 16µs within DBIx::Class::Storage::TxnScopeGuard::BEGIN@7 which was called:
# once (16µs+0s) by DBIx::Class::Storage::BEGIN@17 at line 7 # spent 16µs making 1 call to DBIx::Class::Storage::TxnScopeGuard::BEGIN@7 |
8 | 3 | 18µs | 1 | 6µs | # spent 6µs within DBIx::Class::Storage::TxnScopeGuard::BEGIN@8 which was called:
# once (6µs+0s) by DBIx::Class::Storage::BEGIN@17 at line 8 # spent 6µs making 1 call to DBIx::Class::Storage::TxnScopeGuard::BEGIN@8 |
9 | 3 | 17µs | 2 | 107µs | # spent 56µs (6+50) within DBIx::Class::Storage::TxnScopeGuard::BEGIN@9 which was called:
# once (6µs+50µs) by DBIx::Class::Storage::BEGIN@17 at line 9 # spent 56µs making 1 call to DBIx::Class::Storage::TxnScopeGuard::BEGIN@9
# spent 50µs making 1 call to DBIx::Class::Carp::import |
10 | 3 | 575µs | 2 | 469µs | # spent 238µs (7+231) within DBIx::Class::Storage::TxnScopeGuard::BEGIN@10 which was called:
# once (7µs+231µs) by DBIx::Class::Storage::BEGIN@17 at line 10 # spent 238µs making 1 call to DBIx::Class::Storage::TxnScopeGuard::BEGIN@10
# spent 231µs making 1 call to namespace::clean::import |
11 | |||||
12 | 1 | 300ns | my ($guards_count, $compat_handler, $foreign_handler); | ||
13 | |||||
14 | # spent 71.5ms (8.91+62.6) within DBIx::Class::Storage::TxnScopeGuard::new which was called 294 times, avg 243µs/call:
# 294 times (8.91ms+62.6ms) by DBIx::Class::Storage::txn_scope_guard at line 488 of DBIx/Class/Storage.pm, avg 243µs/call | ||||
15 | 2940 | 8.38ms | my ($class, $storage) = @_; | ||
16 | |||||
17 | my $guard = { | ||||
18 | inactivated => 0, | ||||
19 | storage => $storage, | ||||
20 | }; | ||||
21 | |||||
22 | # we are starting with an already set $@ - in order for things to work we need to | ||||
23 | # be able to recognize it upon destruction - store its weakref | ||||
24 | # recording it before doing the txn_begin stuff | ||||
25 | if (defined $@ and $@ ne '') { | ||||
26 | $guard->{existing_exception_ref} = (ref $@ ne '') ? $@ : \$@; | ||||
27 | weaken $guard->{existing_exception_ref}; | ||||
28 | } | ||||
29 | |||||
30 | 294 | 2.24ms | $storage->txn_begin; # spent 2.24ms making 294 calls to DBIx::Class::Storage::DBI::txn_begin, avg 8µs/call | ||
31 | |||||
32 | 1 | 1µs | $guard->{dbh} = $storage->_dbh; # spent 1µs making 1 call to DBIx::Class::Storage::DBI::_dbh | ||
33 | 294 | 832µs | weaken $guard->{dbh}; # spent 832µs making 294 calls to Scalar::Util::weaken, avg 3µs/call | ||
34 | |||||
35 | bless $guard, ref $class || $class; | ||||
36 | |||||
37 | # install a callback carefully | ||||
38 | if (DBIx::Class::_ENV_::INVISIBLE_DOLLAR_AT and !$guards_count) { | ||||
39 | |||||
40 | # if the thrown exception is a plain string, wrap it in our | ||||
41 | # own exception class | ||||
42 | # this is actually a pretty cool idea, may very well keep it | ||||
43 | # after perl is fixed | ||||
44 | $compat_handler ||= bless( | ||||
45 | sub { | ||||
46 | $@ = (blessed($_[0]) or ref($_[0])) | ||||
47 | ? $_[0] | ||||
48 | : bless ( { msg => $_[0] }, 'DBIx::Class::Exception') | ||||
49 | ; | ||||
50 | die; | ||||
51 | }, | ||||
52 | '__TxnScopeGuard__FIXUP__', | ||||
53 | ); | ||||
54 | |||||
55 | if ($foreign_handler = $SIG{__DIE__}) { | ||||
56 | $SIG{__DIE__} = bless ( | ||||
57 | sub { | ||||
58 | # we trust the foreign handler to do whatever it wants, all we do is set $@ | ||||
59 | eval { $compat_handler->(@_) }; | ||||
60 | $foreign_handler->(@_); | ||||
61 | }, | ||||
62 | '__TxnScopeGuard__FIXUP__', | ||||
63 | ); | ||||
64 | } | ||||
65 | else { | ||||
66 | $SIG{__DIE__} = $compat_handler; | ||||
67 | } | ||||
68 | } | ||||
69 | |||||
70 | $guards_count++; | ||||
71 | |||||
72 | $guard; | ||||
73 | } | ||||
74 | |||||
75 | # spent 34.9s (4.65ms+34.9) within DBIx::Class::Storage::TxnScopeGuard::commit which was called 294 times, avg 119ms/call:
# 147 times (2.40ms+17.7s) by DBIx::Class::Relationship::CascadeActions::update at line 70 of DBIx/Class/Relationship/CascadeActions.pm, avg 120ms/call
# 147 times (2.25ms+17.2s) by DBIx::Class::Row::insert at line 405 of DBIx/Class/Row.pm, avg 117ms/call | ||||
76 | 1176 | 4.85ms | my $self = shift; | ||
77 | |||||
78 | $self->{storage}->throw_exception("Refusing to execute multiple commits on scope guard $self") | ||||
79 | if $self->{inactivated}; | ||||
80 | |||||
81 | 294 | 34.9s | $self->{storage}->txn_commit; # spent 34.9s making 294 calls to DBIx::Class::Storage::DBI::txn_commit, avg 119ms/call | ||
82 | $self->{inactivated} = 1; | ||||
83 | } | ||||
84 | |||||
85 | # spent 4.88ms within DBIx::Class::Storage::TxnScopeGuard::DESTROY which was called 294 times, avg 17µs/call:
# 147 times (2.44ms+0s) by DBIx::Class::Relationship::CascadeActions::update at line 136 of lib/Tapper/MCP/Scheduler/Controller.pm, avg 17µs/call
# 147 times (2.44ms+0s) by DBIx::Class::Row::insert at line 150 of Tapper/Schema/TestrunDB/Result/Testrun.pm, avg 17µs/call | ||||
86 | 1176 | 4.12ms | my $self = shift; | ||
87 | |||||
88 | $guards_count--; | ||||
89 | |||||
90 | # don't touch unless it's ours, and there are no more of us left | ||||
91 | if ( | ||||
92 | DBIx::Class::_ENV_::INVISIBLE_DOLLAR_AT | ||||
93 | and | ||||
94 | !$guards_count | ||||
95 | ) { | ||||
96 | |||||
97 | if (ref $SIG{__DIE__} eq '__TxnScopeGuard__FIXUP__') { | ||||
98 | # restore what we saved | ||||
99 | if ($foreign_handler) { | ||||
100 | $SIG{__DIE__} = $foreign_handler; | ||||
101 | } | ||||
102 | else { | ||||
103 | delete $SIG{__DIE__}; | ||||
104 | } | ||||
105 | } | ||||
106 | |||||
107 | # make sure we do not leak the foreign one in case it exists | ||||
108 | undef $foreign_handler; | ||||
109 | } | ||||
110 | |||||
111 | return if $self->{inactivated}; | ||||
112 | |||||
113 | # if our dbh is not ours anymore, the $dbh weakref will go undef | ||||
114 | $self->{storage}->_verify_pid; | ||||
115 | return unless $self->{dbh}; | ||||
116 | |||||
117 | my $exception = $@ if ( | ||||
118 | defined $@ | ||||
119 | and | ||||
120 | $@ ne '' | ||||
121 | and | ||||
122 | ( | ||||
123 | ! defined $self->{existing_exception_ref} | ||||
124 | or | ||||
125 | refaddr( ref $@ eq '' ? \$@ : $@ ) != refaddr($self->{existing_exception_ref}) | ||||
126 | ) | ||||
127 | ); | ||||
128 | |||||
129 | { | ||||
130 | local $@; | ||||
131 | |||||
132 | carp 'A DBIx::Class::Storage::TxnScopeGuard went out of scope without explicit commit or error. Rolling back.' | ||||
133 | unless defined $exception; | ||||
134 | |||||
135 | my $rollback_exception; | ||||
136 | # do minimal connectivity check due to weird shit like | ||||
137 | # https://rt.cpan.org/Public/Bug/Display.html?id=62370 | ||||
138 | try { $self->{storage}->_seems_connected && $self->{storage}->txn_rollback } | ||||
139 | catch { $rollback_exception = shift }; | ||||
140 | |||||
141 | if ( $rollback_exception and ( | ||||
142 | ! defined blessed $rollback_exception | ||||
143 | or | ||||
144 | ! $rollback_exception->isa('DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION') | ||||
145 | ) ) { | ||||
146 | # append our text - THIS IS A TEMPORARY FIXUP! | ||||
147 | # a real stackable exception object is in the works | ||||
148 | if (ref $exception eq 'DBIx::Class::Exception') { | ||||
149 | $exception->{msg} = "Transaction aborted: $exception->{msg} " | ||||
150 | ."Rollback failed: ${rollback_exception}"; | ||||
151 | } | ||||
152 | elsif ($exception) { | ||||
153 | $exception = "Transaction aborted: ${exception} " | ||||
154 | ."Rollback failed: ${rollback_exception}"; | ||||
155 | } | ||||
156 | else { | ||||
157 | carp (join ' ', | ||||
158 | "********************* ROLLBACK FAILED!!! ********************", | ||||
159 | "\nA rollback operation failed after the guard went out of scope.", | ||||
160 | 'This is potentially a disastrous situation, check your data for', | ||||
161 | "consistency: $rollback_exception" | ||||
162 | ); | ||||
163 | } | ||||
164 | } | ||||
165 | } | ||||
166 | |||||
167 | $@ = $exception unless DBIx::Class::_ENV_::INVISIBLE_DOLLAR_AT; | ||||
168 | } | ||||
169 | |||||
170 | 1 | 3µs | 1; | ||
171 | |||||
172 | 1 | 7µs | 1 | 561µs | __END__ # spent 561µs making 1 call to B::Hooks::EndOfScope::__ANON__[B/Hooks/EndOfScope.pm:26] |