#
# Deliberately *NOT* using is_exception - if someone left a misbehaving
# antipattern value in $@, it's not our business to whine about it
- if( defined $@ and length $@ ) {
- weaken(
- $guard->{existing_exception_ref} = (length ref $@) ? $@ : \$@
- );
- }
+ weaken(
+ $guard->{existing_exception_ref} = (length ref $@) ? $@ : \$@
+ ) if( defined $@ and length $@ );
$storage->txn_begin;
return if $_[0]->{inactivated};
- # if our dbh is not ours anymore, the $dbh weakref will go undef
- $_[0]->{storage}->_verify_pid unless DBIx::Class::_ENV_::BROKEN_FORK;
- return unless $_[0]->{dbh};
+ # grab it before we've done volatile stuff below
my $current_exception = (
is_exception $@
and
: undef
;
- {
- local $@;
-
- carp 'A DBIx::Class::Storage::TxnScopeGuard went out of scope without explicit commit or error. Rolling back.'
- unless defined $current_exception;
-
- my $rollback_exception;
- # do minimal connectivity check due to weird shit like
- # https://rt.cpan.org/Public/Bug/Display.html?id=62370
- eval {
- $_[0]->{storage}->_seems_connected && $_[0]->{storage}->txn_rollback;
- 1;
- } or $rollback_exception = $@;
-
- if ( $rollback_exception and (
- ! defined blessed $rollback_exception
- or
- ! $rollback_exception->isa('DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION')
- ) ) {
- # append our text - THIS IS A TEMPORARY FIXUP!
- # a real stackable exception object is in the works
- if (ref $current_exception eq 'DBIx::Class::Exception') {
- $current_exception->{msg} = "Transaction aborted: $current_exception->{msg} "
- ."Rollback failed: ${rollback_exception}";
- }
- elsif ($current_exception) {
- $current_exception = "Transaction aborted: ${current_exception} "
- ."Rollback failed: ${rollback_exception}";
- }
- else {
- carp (join ' ',
- "********************* ROLLBACK FAILED!!! ********************",
- "\nA rollback operation failed after the guard went out of scope.",
- 'This is potentially a disastrous situation, check your data for',
- "consistency: $rollback_exception"
- );
- }
- }
+
+ # if our dbh is not ours anymore, the $dbh weakref will go undef
+ $_[0]->{storage}->_verify_pid unless DBIx::Class::_ENV_::BROKEN_FORK;
+ return unless defined $_[0]->{dbh};
+
+
+ carp 'A DBIx::Class::Storage::TxnScopeGuard went out of scope without explicit commit or error. Rolling back'
+ unless defined $current_exception;
+
+
+ if (
+ my $rollback_exception = $_[0]->{storage}->__delicate_rollback(
+ defined $current_exception
+ ? \$current_exception
+ : ()
+ )
+ and
+ ! defined $current_exception
+ ) {
+ carp (join ' ',
+ "********************* ROLLBACK FAILED!!! ********************",
+ "\nA rollback operation failed after the guard went out of scope.",
+ 'This is potentially a disastrous situation, check your data for',
+ "consistency: $rollback_exception"
+ );
}
- $@ = $current_exception;
+ $@ = $current_exception
+ if DBIx::Class::_ENV_::UNSTABLE_DOLLARAT;
+
+ # Dummy NEXTSTATE ensuring the all temporaries on the stack are garbage
+ # collected before leaving this scope. Depending on the code above, this
+ # may very well be just a preventive measure guarding future modifications
+ undef;
}
1;