The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

DBI::Transaction::Repeated - repeat database transaction until success.

PURPOSE

Some database systems (e.g. InnoDB engine of MySQL) do not warrant that any particular transaction will succeed because it may collide with concurrent transactions. Documentation suggest to repeat a transaction until it will succeed.

This module accomplishes repeating a transaction until success.

SYNOPSIS

 use DBI::Transaction::Repeated qw(repeat_transaction ERR_OK);

 $DBI::Transaction::Repeated::MAX_REPEAT = 20;

 sub do_transaction {
   my $dbh = shift;
   $dbh->do("INSERT INTO table SET x=23");
   return ERR_OK;
 }

 $err = repeat_transaction($dbh, \&do_transaction);
 die "Transaction failed." unless $err = ERR_OK;

CAVEATS

  • This package currently ignores $dbh->{RaiseError} (sets it to false during transactional operations). So it should never throw exceptions.

    However the callback is called with unchanged {RaiseError} (that value of $dbh->{RaiseError} which was before calling a routine from this package).

  • Any subtransaction embedded into an other transaction may fail with ERR_CANNOT_ROLL.

    If you get this error, you should try to roll back an upper level transaction.

  • See DBI::Transaction(3) about problems with MySQL

DESCRIPTION

new()
  DBI::Transaction::Repeat->new($dbh, \&callback,
                                -count => 100,
                                -args => [...],
                                -PrintDeadlockErrors=>(0|1))

Named parameters are optional.

'count' is maximum number of attempts (default $MAX_REPEAT),

'args' is array of additional arguments to pass to the callback.

If 'PrintDeadlockErrors' is true, this package will warn about deadlocks even if the transaction succeeded on a following attempt. If omitted, 'PrintDeadlockErrors' is set to $dbh->{PrintWarn} (see DBI(3)).

Callback is called with $dbh as the first argument.

Callback must return ERR_OK to indicate success, or ERR_REPEAT to ask to repeat it more. Any other value or throwing an exception from the callback is considered as a failure (ERR_FAILURE).

run()

Run the transaction maximum $MAX_REPEAT times.

TODO: Currently run() must be called no more than once on the same DBI::Transaction::Repeat object. Should be allowed to call it multiple times,.

repeat_transaction()

It is called with the same arguments as new() and is equivalent to

  DBI::Transaction::Repeat->new(@_)->run;

repeat_transaction() can be called either as a normal routine or a method.

step()

Make one step (TODO).

$MAX_REPEAT

The maximum number of repeats attempted.

Currently it is 100 by default.

ERROR CODES

ERR_OK

No error.

ERR_CANNOT_ROLL

Attempt to roll back a subtransaction failed. Try to roll back an upper level transaction.

ERR_REPEAT

(Can be returned only by step() method.) Try again.

ERR_DBI_FAILED

DBI(3) failed while attempting to commit, roll back, or start transaction.

ERR_FAILED

Transaction callback failed (not returned ERR_OK).

ERR_REPEAT_EXCEEDED

Transaction was tried $MAX_REPEAT times without success.

AUTHOR

The original author Victor Porton <porton@ex-code.com> will gladly hear your bug reports.

Module's homepage: http://ex-code.com/dbi-transactions/

LICENSE

General Public License version 2 (see also module's homepage).

SEE ALSO

DBI(3), DBI::Transaction(3)