From: Justin Guenther Date: Wed, 1 Mar 2006 08:34:34 +0000 (+0000) Subject: - Changed documentation to use txn_do() for transactions X-Git-Tag: v0.06000~75 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=181a28f4e04c13a37fe4a5b6357d85e1da63dbc4;p=dbsrgits%2FDBIx-Class.git - Changed documentation to use txn_do() for transactions - Fixed Storage::DBI trace such that each bind parameter is quoted on output, separated by commas - Fixed a couple typos in documentation --- diff --git a/README b/README index dd554e9..ae3a20d 100644 --- a/README +++ b/README @@ -112,7 +112,7 @@ CONTRIBUTORS Scotty Allen - Justin Guenther + Justin Guenther LICENSE You may distribute this code under the same terms as Perl itself. diff --git a/lib/DBIx/Class.pm b/lib/DBIx/Class.pm index 8e44c89..77fddc2 100644 --- a/lib/DBIx/Class.pm +++ b/lib/DBIx/Class.pm @@ -164,6 +164,8 @@ Scotty Allen sc_ +Justin Guenther + =head1 LICENSE You may distribute this code under the same terms as Perl itself. diff --git a/lib/DBIx/Class/DB.pm b/lib/DBIx/Class/DB.pm index 1a4adff..2051b01 100644 --- a/lib/DBIx/Class/DB.pm +++ b/lib/DBIx/Class/DB.pm @@ -67,7 +67,7 @@ it. See resolve_class below. =cut __PACKAGE__->mk_classdata('class_resolver' => - 'DBIx::Class::ClassResolver::PassThrough'); + 'DBIx::Class::ClassResolver::PassThrough'); =head2 connection @@ -106,7 +106,7 @@ Begins a transaction (does nothing if AutoCommit is off). =cut -sub txn_begin { $_[0]->schema_instance->txn_begin } +sub txn_begin { shift->schema_instance->txn_begin(@_); } =head2 txn_commit @@ -114,7 +114,7 @@ Commits the current transaction. =cut -sub txn_commit { $_[0]->schema_instance->txn_commit } +sub txn_commit { shift->schema_instance->txn_commit(@_); } =head2 txn_rollback @@ -122,7 +122,17 @@ Rolls back the current transaction. =cut -sub txn_rollback { $_[0]->schema_instance->txn_rollback } +sub txn_rollback { shift->schema_instance->txn_rollback(@_); } + +=head2 txn_do + +Executes a block of code transactionally. If this code reference +throws an exception, the transaction is rolled back and the exception +is rethrown. See txn_do in L for more details. + +=cut + +sub txn_do { shift->schema_instance->txn_do(@_); } { my $warn; diff --git a/lib/DBIx/Class/Manual/Cookbook.pod b/lib/DBIx/Class/Manual/Cookbook.pod index 1ab0e31..10ea023 100644 --- a/lib/DBIx/Class/Manual/Cookbook.pod +++ b/lib/DBIx/Class/Manual/Cookbook.pod @@ -352,29 +352,42 @@ SQL statements: =head2 Transactions As of version 0.04001, there is improved transaction support in -L. Here is an example of the recommended -way to use it: +L and L. Here is an +example of the recommended way to use it: - my $genus = Genus->find(12); - eval { - MyDB->txn_begin; + my $genus = $schema->resultset('Genus')->find(12); + + my $coderef1 = sub { + my ($schema, $genus, $code) = @_; $genus->add_to_species({ name => 'troglodyte' }); $genus->wings(2); $genus->update; - cromulate($genus); # Can have a nested transation - MyDB->txn_commit; + $schema->txn_do($code, $genus); # Can have a nested transation + return $genus->species; + }; + + my $coderef2 = sub { + my ($genus) = @_; + $genus->extinct(1); + $genus->update; }; - if ($@) { - # Rollback might fail, too - eval { - MyDB->txn_rollback - }; + + my $rs; + eval { + $rs = $schema->txn_do($coderef1, $schema, $genus, $coderef2); + }; + + if ($@) { # Transaction failed + die "the sky is falling!" # + if ($@ =~ /Rollback failed/); # Rollback failed + + deal_with_failed_transaction(); } -Currently, a nested commit will do nothing and a nested rollback will -die. The code at each level must be sure to call rollback in the case -of an error, to ensure that the rollback will propagate to the top -level and be issued. Support for savepoints and for true nested +Nested transactions will work as expected. That is, only the outermost +transaction will actually issue a commit to the $dbh, and a rollback +at any level of any transaction will cause the entire nested +transaction to fail. Support for savepoints and for true nested transactions (for databases that support them) will hopefully be added in the future. diff --git a/lib/DBIx/Class/ResultSet.pm b/lib/DBIx/Class/ResultSet.pm index 216b0c7..f1ca440 100644 --- a/lib/DBIx/Class/ResultSet.pm +++ b/lib/DBIx/Class/ResultSet.pm @@ -55,7 +55,7 @@ In the examples below, the following table classes are used: =head3 Arguments: ($source, \%$attrs) The resultset constructor. Takes a source object (usually a -L) and an attribute hash (see L +L) and an attribute hash (see L below). Does not perform any queries -- these are executed as needed by the other methods. diff --git a/lib/DBIx/Class/Schema.pm b/lib/DBIx/Class/Schema.pm index 631d5aa..3b25530 100644 --- a/lib/DBIx/Class/Schema.pm +++ b/lib/DBIx/Class/Schema.pm @@ -61,7 +61,7 @@ particular which module inherits off which. Registers a class which isa ResultSourceProxy; equivalent to calling - $schema->register_source($moniker, $class->result_source_instance); + $schema->register_source($moniker, $component_class->result_source_instance); =cut @@ -373,12 +373,13 @@ sub txn_rollback { shift->storage->txn_rollback } =head2 txn_do -=head3 Arguments: , [@coderef_args] +=head3 Arguments: <$coderef>, [@coderef_args] -Executes with (optional) arguments <@coderef_args> transactionally, -returning its result (if any). If an exception is caught, a rollback is issued -and the exception is rethrown. If the rollback fails, (i.e. throws an -exception) an exception is thrown that includes a "Rollback failed" message. +Executes C<$coderef> with (optional) arguments C<@coderef_args> +transactionally, returning its result (if any). If an exception is +caught, a rollback is issued and the exception is rethrown. If the +rollback fails, (i.e. throws an exception) an exception is thrown that +includes a "Rollback failed" message. For example, @@ -410,7 +411,7 @@ For example, } } -Nested transactions should work as expected (i.e. only the outermost +Nested transactions work as expected (i.e. only the outermost transaction will issue a txn_commit on the Schema's storage) =cut diff --git a/lib/DBIx/Class/Storage/DBI.pm b/lib/DBIx/Class/Storage/DBI.pm index 28c0706..b415445 100644 --- a/lib/DBIx/Class/Storage/DBI.pm +++ b/lib/DBIx/Class/Storage/DBI.pm @@ -336,11 +336,15 @@ sub _connect { Calls begin_work on the current dbh. +See L for the txn_do() method, which allows for +an entire code block to be executed transactionally. + =cut sub txn_begin { my $self = shift; - $self->dbh->begin_work if $self->{transaction_depth}++ == 0 and $self->dbh->{AutoCommit}; + $self->dbh->begin_work + if $self->{transaction_depth}++ == 0 and $self->dbh->{AutoCommit}; } =head2 txn_commit @@ -361,7 +365,9 @@ sub txn_commit { =head2 txn_rollback -Issues a rollback against the current dbh. +Issues a rollback against the current dbh. A nested rollback will +throw a L exception, +which allows the rollback to propagate to the outermost transaction. =cut @@ -393,8 +399,8 @@ sub _execute { my ($sql, @bind) = $self->sql_maker->$op($ident, @args); unshift(@bind, @$extra_bind) if $extra_bind; if ($self->debug) { - my @debug_bind = map { defined $_ ? $_ : 'NULL' } @bind; - $self->debugfh->print("$sql: @debug_bind\n"); + my @debug_bind = map { defined $_ ? qq{`$_'} : q{`NULL'} } @bind; + $self->debugfh->print("$sql: " . join(', ', @debug_bind) . "\n"); } my $sth = $self->sth($sql,$op); croak "no sth generated via sql: $sql" unless $sth;