- Changed documentation to use txn_do() for transactions
Justin Guenther [Wed, 1 Mar 2006 08:34:34 +0000 (08:34 +0000)]
- Fixed Storage::DBI trace such that each bind parameter is quoted on output, separated by commas
- Fixed a couple typos in documentation

README
lib/DBIx/Class.pm
lib/DBIx/Class/DB.pm
lib/DBIx/Class/Manual/Cookbook.pod
lib/DBIx/Class/ResultSet.pm
lib/DBIx/Class/Schema.pm
lib/DBIx/Class/Storage/DBI.pm

diff --git a/README b/README
index dd554e9..ae3a20d 100644 (file)
--- a/README
+++ b/README
@@ -112,7 +112,7 @@ CONTRIBUTORS
 
     Scotty Allen <scotty@scottyallen.com>
 
-    Justin Guenther <jguenther@gmail.com>
+    Justin Guenther <guentherj@agr.gc.ca>
 
 LICENSE
     You may distribute this code under the same terms as Perl itself.
index 8e44c89..77fddc2 100644 (file)
@@ -164,6 +164,8 @@ Scotty Allen <scotty@scottyallen.com>
 
 sc_
 
+Justin Guenther <jguenther@agr.gc.ca>
+
 =head1 LICENSE
 
 You may distribute this code under the same terms as Perl itself.
index 1a4adff..2051b01 100644 (file)
@@ -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<DBIx::Class::Schema> for more details.
+
+=cut
+
+sub txn_do { shift->schema_instance->txn_do(@_); }
 
 {
   my $warn;
index 1ab0e31..10ea023 100644 (file)
@@ -352,29 +352,42 @@ SQL statements:
 =head2 Transactions
 
 As of version 0.04001, there is improved transaction support in
-L<DBIx::Class::Storage::DBI>.  Here is an example of the recommended
-way to use it:
+L<DBIx::Class::Storage::DBI> and L<DBIx::Class::Schema>.  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.
 
index 216b0c7..f1ca440 100644 (file)
@@ -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<DBIx::Class::ResultSourceProxy::Table>) and an attribute hash (see L</ATRRIBUTES>
+L<DBIx::Class::ResultSourceProxy::Table>) and an attribute hash (see L</ATTRIBUTES>
 below).  Does not perform any queries -- these are executed as needed by the
 other methods.
 
index 631d5aa..3b25530 100644 (file)
@@ -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>, [@coderef_args]
+=head3 Arguments: <$coderef>, [@coderef_args]
 
-Executes <coderef> 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
index 28c0706..b415445 100644 (file)
@@ -336,11 +336,15 @@ sub _connect {
 
 Calls begin_work on the current dbh.
 
+See L<DBIx::Class::Schema> 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<DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION> 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;