DBIO

 view release on metacpan or  search on metacpan

lib/DBIO/Storage.pm  view on Meta::CPAN




sub throw_exception {
  my $self = shift;

  if (ref $self and $self->schema) {
    $self->schema->throw_exception(@_);
  }
  else {
    DBIO::Exception->throw(@_);
  }
}



sub txn_do {
  my $self = shift;
  $self->_throw_deferred_rollback if $self->deferred_rollback;

  DBIO::Storage::BlockRunner->new(
    storage => $self,
    wrap_txn => 1,
    retry_handler => sub {
      $_[0]->failed_attempt_count == 1
        and
      ! $_[0]->storage->connected
    },
  )->run(@_);
}



sub txn_begin {
  my $self = shift;
  $self->_throw_deferred_rollback if $self->deferred_rollback;
  $self->_assert_transaction_safe_access_broker;

  if($self->transaction_depth == 0) {
    $self->debugobj->txn_begin()
      if $self->debug;
    $self->_exec_txn_begin;
  }
  elsif ($self->auto_savepoint) {
    $self->svp_begin;
  }
  $self->{transaction_depth}++;

}

sub _assert_transaction_safe_access_broker {
  my $self = shift;

  return if $self->{_access_broker_txn_safety_checked};
  return if $self->transaction_depth;

  my $broker = $self->access_broker or return;
  return if $broker->is_transaction_safe;

  my @reasons;
  push @reasons, 'credential rotation' if $broker->has_rotating_credentials;
  my $reason = @reasons
    ? join(' and ', @reasons)
    : 'broker-specific transaction safety constraints';

  if ($ENV{DBIO_ALLOW_UNSAFE_BROKER_TRANSACTIONS}) {
    carp sprintf(
      'Starting a transaction with unsafe AccessBroker %s via override: %s',
      ref($broker) || $broker,
      $reason,
    );
    return;
  }

  $self->throw_exception(sprintf(
    'Refusing to start a transaction with unsafe AccessBroker %s: %s can break transactional consistency',
    ref($broker) || $broker,
    $reason,
  ));
}



sub txn_commit {
  my $self = shift;
  $self->_throw_deferred_rollback if $self->deferred_rollback;

  if ($self->transaction_depth == 1) {
    $self->debugobj->txn_commit() if $self->debug;
    $self->_exec_txn_commit;
    $self->{transaction_depth}--;
    $self->savepoints([]);
  }
  elsif($self->transaction_depth > 1) {
    $self->{transaction_depth}--;
    $self->svp_release if $self->auto_savepoint;
  }
  else {
    $self->throw_exception( 'Refusing to commit without a started transaction' );
  }
}



sub txn_rollback {
  my $self = shift;

  if ($self->transaction_depth == 1) {
    $self->debugobj->txn_rollback() if $self->debug;
    $self->_exec_txn_rollback;
    $self->{transaction_depth}--;
    $self->savepoints([]);
    $self->deferred_rollback(undef);
  }
  elsif ($self->transaction_depth > 1) {
    $self->{transaction_depth}--;

    if ($self->auto_savepoint) {
      $self->svp_rollback;
      $self->svp_release;
    }



( run in 0.584 second using v1.01-cache-2.11-cpan-f52f0507bed )