Another overhaul (hopefully one of the last ones) of the rollback handling
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Storage / BlockRunner.pm
index 05fe475..ad9cbf7 100644 (file)
@@ -1,14 +1,16 @@
 package # hide from pause until we figure it all out
   DBIx::Class::Storage::BlockRunner;
 
-use Sub::Quote 'quote_sub';
+use warnings;
+use strict;
+
 use DBIx::Class::Exception;
 use DBIx::Class::Carp;
 use Context::Preserve 'preserve_context';
+use DBIx::Class::_Util qw(is_exception qsub);
 use Scalar::Util qw(weaken blessed reftype);
 use Try::Tiny;
 use Moo;
-use warnings NONFATAL => 'all';
 use namespace::clean;
 
 =head1 NAME
@@ -35,16 +37,16 @@ has wrap_txn => (
 has retry_handler => (
   is => 'ro',
   required => 1,
-  isa => quote_sub( q{
+  isa => qsub q{
     (Scalar::Util::reftype($_[0])||'') eq 'CODE'
       or DBIx::Class::Exception->throw('retry_handler must be a CODE reference')
-  }),
+  },
 );
 
 has retry_debug => (
   is => 'rw',
   # use a sub - to be evaluated on the spot lazily
-  default => quote_sub( '$ENV{DBIC_STORAGE_RETRY_DEBUG}' ),
+  default => qsub '$ENV{DBIC_STORAGE_RETRY_DEBUG}',
   lazy => 1,
 );
 
@@ -59,19 +61,19 @@ has failed_attempt_count => (
   writer => '_set_failed_attempt_count',
   default => 0,
   lazy => 1,
-  trigger => quote_sub(q{
+  trigger => qsub q{
     $_[0]->throw_exception( sprintf (
       'Reached max_attempts amount of %d, latest exception: %s',
       $_[0]->max_attempts, $_[0]->last_exception
     )) if $_[0]->max_attempts <= ($_[1]||0);
-  }),
+  },
 );
 
 has exception_stack => (
   is => 'ro',
   init_arg => undef,
   clearer => '_reset_exception_stack',
-  default => quote_sub(q{ [] }),
+  default => qsub q{ [] },
   lazy => 1,
 );
 
@@ -136,7 +138,7 @@ sub _run {
     my $storage = $self->storage;
     my $cur_depth = $storage->transaction_depth;
 
-    if (defined $txn_init_depth and $run_err eq '') {
+    if (defined $txn_init_depth and ! is_exception $run_err) {
       my $delta_txn = (1 + $txn_init_depth) - $cur_depth;
 
       if ($delta_txn) {
@@ -154,24 +156,12 @@ sub _run {
     }
 
     # something above threw an error (could be the begin, the code or the commit)
-    if ($run_err ne '') {
-
-      # attempt a rollback if we did begin in the first place
-      if ($txn_begin_ok) {
-        # some DBDs go crazy if there is nothing to roll back on, perform a soft-check
-        my $rollback_exception = $storage->_seems_connected
-          ? (! eval { $storage->txn_rollback; 1 }) ? $@ : ''
-          : 'lost connection to storage'
-        ;
-
-        if ( $rollback_exception and (
-          ! defined blessed $rollback_exception
-            or
-          ! $rollback_exception->isa('DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION')
-        ) ) {
-          $run_err = "Transaction aborted: $run_err. Rollback failed: $rollback_exception";
-        }
-      }
+    if ( is_exception $run_err ) {
+
+      # Attempt a rollback if we did begin in the first place
+      # Will append rollback error if possible
+      $storage->__delicate_rollback( \$run_err )
+        if $txn_begin_ok;
 
       push @{ $self->exception_stack }, $run_err;
 
@@ -211,13 +201,16 @@ sub _run {
   };
 }
 
-=head1 AUTHOR AND CONTRIBUTORS
+=head1 FURTHER QUESTIONS?
 
-See L<AUTHOR|DBIx::Class/AUTHOR> and L<CONTRIBUTORS|DBIx::Class/CONTRIBUTORS> in DBIx::Class
+Check the list of L<additional DBIC resources|DBIx::Class/GETTING HELP/SUPPORT>.
 
-=head1 LICENSE
+=head1 COPYRIGHT AND LICENSE
 
-You may distribute this code under the same terms as Perl itself.
+This module is free software L<copyright|DBIx::Class/COPYRIGHT AND LICENSE>
+by the L<DBIx::Class (DBIC) authors|DBIx::Class/AUTHORS>. You can
+redistribute it and/or modify it under the same terms as the
+L<DBIx::Class library|DBIx::Class/COPYRIGHT AND LICENSE>.
 
 =cut