| 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 | DBIx::Class::Storage::TxnScopeGuard::new |
| 294 | 2 | 2 | 4.88ms | 4.88ms | DBIx::Class::Storage::TxnScopeGuard::DESTROY |
| 294 | 2 | 2 | 4.65ms | 34.9s | DBIx::Class::Storage::TxnScopeGuard::commit |
| 1 | 1 | 1 | 16µs | 16µs | DBIx::Class::Storage::TxnScopeGuard::BEGIN@7 |
| 1 | 1 | 1 | 12µs | 14µs | DBIx::Class::Storage::TxnScopeGuard::BEGIN@3 |
| 1 | 1 | 1 | 10µs | 46µs | DBIx::Class::Storage::TxnScopeGuard::BEGIN@5 |
| 1 | 1 | 1 | 7µs | 34µs | DBIx::Class::Storage::TxnScopeGuard::BEGIN@6 |
| 1 | 1 | 1 | 7µs | 238µs | DBIx::Class::Storage::TxnScopeGuard::BEGIN@10 |
| 1 | 1 | 1 | 7µs | 15µs | DBIx::Class::Storage::TxnScopeGuard::BEGIN@4 |
| 1 | 1 | 1 | 6µs | 6µs | DBIx::Class::Storage::TxnScopeGuard::BEGIN@8 |
| 1 | 1 | 1 | 6µs | 56µs | DBIx::Class::Storage::TxnScopeGuard::BEGIN@9 |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::Storage::TxnScopeGuard::__ANON__[:138] |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::Storage::TxnScopeGuard::__ANON__[:139] |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::Storage::TxnScopeGuard::__ANON__[:51] |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::Storage::TxnScopeGuard::__ANON__[:61] |
| 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 | 294 | 397µs | my ($class, $storage) = @_; | ||
| 16 | |||||
| 17 | 294 | 915µs | 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 | 294 | 370µs | if (defined $@ and $@ ne '') { | ||
| 26 | $guard->{existing_exception_ref} = (ref $@ ne '') ? $@ : \$@; | ||||
| 27 | weaken $guard->{existing_exception_ref}; | ||||
| 28 | } | ||||
| 29 | |||||
| 30 | 294 | 1.08ms | 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 | 294 | 693µs | 1 | 1µs | $guard->{dbh} = $storage->_dbh; # spent 1µs making 1 call to DBIx::Class::Storage::DBI::_dbh |
| 33 | 294 | 2.12ms | 294 | 832µs | weaken $guard->{dbh}; # spent 832µs making 294 calls to Scalar::Util::weaken, avg 3µs/call |
| 34 | |||||
| 35 | 294 | 1.40ms | bless $guard, ref $class || $class; | ||
| 36 | |||||
| 37 | # install a callback carefully | ||||
| 38 | 294 | 61µs | 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 | 294 | 146µs | $guards_count++; | ||
| 71 | |||||
| 72 | 294 | 1.19ms | $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 | 294 | 143µs | my $self = shift; | ||
| 77 | |||||
| 78 | 294 | 287µs | $self->{storage}->throw_exception("Refusing to execute multiple commits on scope guard $self") | ||
| 79 | if $self->{inactivated}; | ||||
| 80 | |||||
| 81 | 294 | 1.05ms | 294 | 34.9s | $self->{storage}->txn_commit; # spent 34.9s making 294 calls to DBIx::Class::Storage::DBI::txn_commit, avg 119ms/call |
| 82 | 294 | 3.37ms | $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 | 294 | 956µs | my $self = shift; | ||
| 87 | |||||
| 88 | 294 | 308µs | $guards_count--; | ||
| 89 | |||||
| 90 | # don't touch unless it's ours, and there are no more of us left | ||||
| 91 | 294 | 108µs | 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 | 294 | 2.74ms | 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] |