bronto has asked for the wisdom of the Perl Monks concerning the following question:

Hello brothers and sisters

I am writing a code that, at a certain point, will have to modify some data on a directory server; what I would like to do is to make my program work in a transaction-like fashion, that is: if any of the update fails, rollback all the changes we made so far and then stop. I am using the perl-ldap-0.26 distribution.

I sketched the snippet that should do the transaction:

my @commits = qw(user secg something more here) ; my @rollbacks ; my $do_rollback ; # dispatch table for commits my %dt_commit = ( user => sub { # try to update an entry or die # ...code here... }, secg => sub { # try to update another entry or die # ...code here... }, # ... et cetera... ) ; my %dt_rollback = ( # same as above, but this dispatch table contains # rollback subs instead of commit ones ) ; foreach my $cmt (@commits) { eval { &{$dt_commit{$cmt}} } ; if ($@) { @rollbacks = reverse @rollbacks ; $do_rollback = 'yes' ; last ; } push @rollbacks,$cmt ; } if ($do_rollback) { foreach my $rbk (@rollbacks) { # execute the rollback subs here } die "Something weird happened, stopping!" ; }

Is it ok? Am I forgetting something important? Could I code it in a better way?

Thanks for help

Ciao!
--bronto

# Another Perl edition of a song:
# The End, by The Beatles
END {
  $you->take($love) eq $you->make($love) ;
}

Replies are listed 'Best First'.
Re: how to build a transaction?
by joe++ (Friar) on Sep 20, 2002 at 12:23 UTC
    Hmm...
    Looks fine for a start to me. I would like to be very sure that not one of the commits could trigger a fatal error, which would terminate the script before rolbacks are done. Maybe a __DIE__ handler could help here, or a DESTROY sub if you're wrapping your script in an OO package. These all would be futile in case of network failure, though.

    Maybe you could create something with temporary records, or at least make backups of the changes. An audit log comes to mind...

    Also, make sure that the rollback order (reversed commit order) is always OK and there are no cross dependencies which prevent this from working.

    Good luck!

    --
    Cheers, Joe

Re: how to build a transaction?
by Michalis (Pilgrim) on Sep 27, 2002 at 09:08 UTC
    May I suggest to use DBD::LDAP ?
    It has builtin support for transactions (actually, pseudo, but someone else has already done it :)
    Michalis