use Exporter::Tidy default => [ qw(transaction select_handle commit rollback) ]; sub select_handle { require Carp; Carp::croak("Can't select handle outside transaction"); } sub _cant_change { require Carp; Carp::croak("Can't change handle during transaction"); } sub transaction (&) { my ($block) = @_; my ($caller, $handle); my $caller = caller(); local *{"${caller}::select_handle"} = sub { $handle = shift; *{"${caller}::select_handle"} = \&_cant_change; }; # ... }