[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