[Dbix-class] Re: Transactions and AutoCommit
Josef Karthauser
joe at tao.org.uk
Sat Jan 27 10:25:32 GMT 2007
On Sat, Jan 27, 2007 at 09:28:34AM +0000, Josef Karthauser wrote:
>
> What I propose is removing the unnecessary complexity.
>
The code change I propose is something like this. I've moved all the
nested level checking into the txn_{begin,commit,rollback} functions.
They then decide to call _dbh_txn_{begin,commit,rollback} or new
functions _dbh_txn_nested_{begin,commit,rollback}, depending upon
what commit level they are operating at. By default the functions
_dbh_txn_nested_{begin,commit} do nothing and are just stubs, and the
nested rollback causes an exception.
The _dbh_txn_nested_* functions are candidates for over-riding in
the .../DBI/database.pm files so that each driver can implement a
level of nesting if they want. For example the mysql driver can support
a level of nested commits using the SQL syntax,
SAVEPOINT identifier
ROLLBACK [WORK] TO SAVEPOINT identifier
RELEASE SAVEPOINT identifier,
and so with these changes to .../Storage/DBI.pm it is a relatively
simple matter to implement this.
The second thing this patch does is remove the dependancy upon the
AutoCommit, so that it trusts DBI's judgement as to whether a
transaction command is valid or not, and propagates any errors back
to the caller.
Joe
=== lib/DBIx/Class/Storage/DBI.pm
==================================================================
--- lib/DBIx/Class/Storage/DBI.pm (revision 3063)
+++ lib/DBIx/Class/Storage/DBI.pm (local)
@@ -741,67 +741,66 @@
sub _dbh_txn_begin {
my ($self, $dbh) = @_;
- if ($dbh->{AutoCommit}) {
- $self->debugobj->txn_begin()
- if ($self->debug);
- $dbh->begin_work;
- }
+ $self->debugobj->txn_begin() if ($self->debug);
+ $dbh->begin_work;
}
+sub _dbh_txn_nested_begin {
+ my ($self, $dbh) = @_;
+ # Do nothing; by default databases don't support nested transactions.
+}
+
sub txn_begin {
my $self = shift;
- $self->dbh_do($self->can('_dbh_txn_begin'))
- if $self->{transaction_depth}++ == 0;
+ $self->ensure_connected();
+ if ($self->{transaction_depth}++ == 0) {
+ $self->dbh_do($self->can('_dbh_txn_begin'));
+ } else {
+ $self->dbh_do($self->can('_dbh_txn_nested_begin'));
+ }
}
sub _dbh_txn_commit {
my ($self, $dbh) = @_;
- if ($self->{transaction_depth} == 0) {
- unless ($dbh->{AutoCommit}) {
- $self->debugobj->txn_commit()
- if ($self->debug);
- $dbh->commit;
- }
- }
- else {
- if (--$self->{transaction_depth} == 0) {
- $self->debugobj->txn_commit()
- if ($self->debug);
- $dbh->commit;
- }
- }
+ $self->debugobj->txn_commit() if ($self->debug);
+ $dbh->commit;
}
+sub _dbh_txn_nested_commit {
+ my ($self, $dbh) = @_;
+ # Do nothing; by default databases don't support nested transactions.
+}
+
sub txn_commit {
my $self = shift;
- $self->dbh_do($self->can('_dbh_txn_commit'));
+ if (--$self->{transaction_depth} <= 0) {
+ $self->{transaction_depth} = 0;
+ $self->dbh_do($self->can('_dbh_txn_commit'));
+ } else {
+ $self->dbh_do($self->can('_dbh_txn_nested_commit'));
+ }
}
sub _dbh_txn_rollback {
my ($self, $dbh) = @_;
- if ($self->{transaction_depth} == 0) {
- unless ($dbh->{AutoCommit}) {
- $self->debugobj->txn_rollback()
- if ($self->debug);
- $dbh->rollback;
- }
- }
- else {
- if (--$self->{transaction_depth} == 0) {
- $self->debugobj->txn_rollback()
- if ($self->debug);
- $dbh->rollback;
- }
- else {
- die DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION->new;
- }
- }
+ $self->debugobj->txn_rollback() if ($self->debug);
+ $dbh->rollback;
}
+sub _dbh_txn_nested_rollback {
+ my ($self, $dbh) = @_;
+ die DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION->new;
+}
+
sub txn_rollback {
my $self = shift;
- eval { $self->dbh_do($self->can('_dbh_txn_rollback')) };
+ if (--$self->{transaction_depth} <= 0) {
+ $self->{transaction_depth} = 0;
+ eval { $self->dbh_do($self->can('_dbh_txn_rollback')) };
+ } else {
+ eval { $self->dbh_do($self->can('_dbh_txn_nested_rollback')) };
+ }
if ($@) {
my $error = $@;
my $exception_class = "DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION";
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 195 bytes
Desc: not available
Url : http://lists.scsys.co.uk/pipermail/dbix-class/attachments/20070127/36a2fa73/attachment.pgp
More information about the Dbix-class
mailing list