[Dbix-class] Transaction depth problem
Dave Cardwell
list+dbix-class at davecardwell.co.uk
Fri Aug 3 10:39:12 GMT 2007
Hello there.
When I run the attached script the call to txn_do() seems to create a
transaction depth of two, so the insert is never actually committed. I
see the insert in the MySQL log and the auto increment value of the
primary key is increased, but the row of data is never actually
inserted.
I have included:
./test.pl
./TestDB.pm
./TestDB/Registration.pm
The table schema is in Registration.pm.
-- =
Best wishes,
Dave Cardwell.
http://davecardwell.co.uk/perl/
-------------- next part --------------
#!/usr/bin/perl
use strict;
use warnings;
use TestDB;
use Carp qw( carp croak );
my $dbi_dsn =3D 'dbi:mysql:dbname=3Dtest;host=3Dlocalhost';
my $user =3D 'DEFINE ME';
my $pass =3D 'DEFINE ME';
my $schema =3D TestDB->connect($dbi_dsn, $user, $pass, {
AutoCommit =3D> 0,
PrintError =3D> 0,
RaiseError =3D> 1,
ShowErrorStatement =3D> 1,
});
carp 'Depth before txn_do: ' . $schema->storage->{transaction_depth};
my $rs;
eval {
$schema->txn_do(sub{
carp 'Depth before create: ' . $schema->storage->{transaction_depth=
};
=
$rs =3D $schema->resultset('Registration')->create({
name =3D> 'Foo Bar',
email =3D> 'foo at bar.com',
password =3D> [ 'SHA1(?)', 'foobar' ],
time =3D> '2007-08-03T09:16:30'
});
=
carp 'Depth after create: ' . $schema->storage->{transaction_depth};
});
=
# With an explicit commit, it works as expected:
# $schema->txn_commit();
};
carp 'Depth after txn_do: ' . $schema->storage->{transaction_depth};
if ( $@ ) {
croak "Fail: $@";
}
else {
# Even when a row of data isn't actually inserted, the primary key is s=
till
# auto-incremented.
carp 'Success: id #' . $rs->get_column('id');
}
# Avoid no explicit disconnect warning - same behaviour with or without.
$schema->storage->disconnect();
1;
-------------- next part --------------
package TestDB;
use strict;
use warnings;
use base qw/ DBIx::Class::Schema /;
__PACKAGE__->load_classes();
1;
-------------- next part --------------
package TestDB::Registration;
use strict;
use warnings;
use base qw/ DBIx::Class /;
# CREATE TABLE `registration` (
# `id` MEDIUMINT( 8) UNSIGNED NOT NULL UNIQU=
E AUTO_INCREMENT,
# `name` VARCHAR( 40) NOT NULL,
# `email` VARCHAR( 80) NOT NULL,
# `password` CHAR( 40) NOT NULL,
# `time` DATETIME NOT NULL,
# =
# PRIMARY KEY ( `id` )
# ) ENGINE=3DInnoDB DEFAULT CHARSET=3D'utf8';
__PACKAGE__->load_components(qw/ Core /);
__PACKAGE__->table('registration');
__PACKAGE__->add_columns(
id =3D> {
data_type =3D> 'MEDIUMINT',
default_value =3D> undef,
is_auto_increment =3D> 1,
is_nullable =3D> 0,
size =3D> 8,
extras =3D> {
unsigned =3D> 1,
},
},
name =3D> {
data_type =3D> 'VARCHAR',
default_value =3D> '',
is_nullable =3D> 0,
size =3D> 40,
},
email =3D> {
data_type =3D> 'VARCHAR',
default_value =3D> '',
is_nullable =3D> 0,
size =3D> 80,
},
password =3D> {
data_type =3D> 'CHAR',
default_value =3D> '',
is_nullable =3D> 0,
size =3D> 40,
},
time =3D> {
data_type =3D> 'DATETIME',
default_value =3D> '',
is_nullable =3D> 0,
size =3D> 19,
}
);
__PACKAGE__->set_primary_key('id');
__PACKAGE__->add_unique_constraint( id =3D> [qw/ id /] );
1;
More information about the DBIx-Class
mailing list