use strict; use warnings; package DB::Transaction; use base qw(Exporter); our $VERSION = 0.001000; # 0.001.0 our @EXPORT_OK = qw(run_in_transaction); my %on_error_options = ( rollback => undef, continue => undef, ); my %transactions_deep; sub run_in_transaction (&;@) { my $code = shift; my (%args) = @_; my $db_handle = $args{db_handle}; my $on_error = $args{on_error} || 'rollback'; die "Don't know how to handle error action '$on_error'\n" if ! exists $on_error_options{$on_error}; local $db_handle->{AutoCommit} = 0; local $db_handle->{RaiseError} = 1; $transactions_deep{"$db_handle"}++; my $error; eval { $code->(); $db_handle->commit if $transactions_deep{"$db_handle"} <= 1; ;1 } || do { $error = defined $@ ? $@ : 'an error was encountered in your transaction'; $db_handle->rollback if $on_error eq 'rollback'; }; $@ = $error if defined $error; $transactions_deep{"$db_handle"}--; delete $transactions_deep{"$db_handle"} if $transactions_deep{"$db_handle"} < 1; die $error if defined $error && $on_error eq 'rollback'; return ! defined $error; } 1; __END__ =head1 NAME DB::Transaction - feather-weight transaction management for your DBI handles =head1 SYNOPSIS use DB::Transaction qw(run_in_transaction); my $dbh = My::Application->get_dbh; run_in_transaction { $dbh->do(' update risky_business -- in some fashion '); } db_handle => $dbh, on_error => 'rollback'; =head1 DESCRIPTION DB::Transaction provides one function: run_in_transaction =head1 EXPORTS By default, none. On request, C. =head2 run_in_transaction BLOCK db_handle => $db_handle, on_error => ['rollback' | 'continue'] Begin a transaction on $db_handle, then run BLOCK. Any errors raised in the course of executing BLOCK will cause the current transaction to be handled according to your C specification. C may be one of these two options: =over 4 =item * rollback -- call this dbh's ->rollback method =item * continue -- just keep on chugging, man! =back C 'rollback'> is the default behavior. Transactions may be nested, though your underlying database may not support nested transactions. It's up to you to know whether this is supported or not. =head1 CONTRIBUTING To contribute back to this project, log in to your GitHub account and visit L, then fork the repository. Create a feature branch, make your changes, push them back to your fork, and submit a pull request via GitHub. # fork the project in github git clone git://github.com//perl-db-transaction.git git checkout -b feature-add-spiffy-functionality emacs -nw t/spiffy-functionality.t # hack hack hack emacs -nw lib/DB/Transaction.pm # hack hack hack git push feature-add-spiffy-functionality origin # submit pull request via github =head1 AUTHORS Written by Aaron Cohen and Belden Lyman at Shutterstock, Inc. Released to CPAN by Shutterstock, Inc. If you like the idea of working at a company that supports open-source development, why not checkout our L and drop us a line? =head1 COPYRIGHT AND LICENSE (c) 2013 Shutterstock, Inc. All rights reserved. This library is free software: you may redistribute it and/or modify it under the same terms as Perl itself; either Perl version 5.8.8 or, at your option, any later version of Perl 5 you may have available.