On Tue, Dec 25, 2001 at 03:26:49AM +0100, Christian Jaeger wrote:
> I'm now crossposting to msql-mysql-modules since that might be more 
> appropriate.
> 
> At 9:13 Uhr -0600 22.12.2001, Philip Molter wrote:
> >On Sat, Dec 22, 2001 at 03:16:45PM +0100, Christian Jaeger wrote:
> >: Hello
> >:
> >: It seems there is a feature in DBD::mysql (when used with InnoDB)
> >: that get's in the way in some circumstances:
> >:
> >: We are doing some code like the following (in a mod_perl environment)
> >: with $dbh being opened with RaiseError and Autocommit=0:
> >
> >We run MySQL-InnoDB in the same type of environment.  We've found
> >that a better way is to only turn AutoCommit off when you need it
> >turned off (using $dbh->{'AutoCommit'} = 0|1).  That way, you don't
> >have to issue the initial commit().
> 
> Well I've now actually tried out ->begin_work, but this gives another 
> problem (I consider it a bug):
> 
> #!/usr/bin/perl -w
> use strict;
> use DBI;
> sub HALT {
>       print "<enter> please..\n"; <STDIN>;
> }
> 
> my $DB= DBI->connect("DBI:mysql:test", "", "", { RaiseError => 1});
> #$DB->do("create table concurrencytest (a int not null primary key, b 
> int) type=innodb");
> my $i=$DB->prepare("insert into concurrencytest values(?,?)");
> 
> $DB->begin_work;
> $i->execute(111,1);
> HALT; # pls restart mysql here!
> $i->execute(112,1);
> $DB->rollback;
> 
> __END__
> 
> Now 'select * from concurrencytest' and you will get:
> +-----+------+
> | a   | b    |
> +-----+------+
> | 112 |    1 |
> +-----+------+
> 
> This means that DBD/DBI reconnect silently without realizing that 
> there is a transaction going on. That's bad! It should throw an 
> exception instead so we can redo what we have begun.

I agree. It's a serious bug.

> (When using AutoCommit=0, commit will give an exception after a 
> reconnect so everything is fine except for the problem which lead me 
> to my first mail - I'm putting it here again for those on the 
> msql-mysql-list:
> 
> >We are doing some code like the following (in a mod_perl 
> >environment) with $dbh being opened with RaiseError and Autocommit=0:
> >
> >$dbh->commit; # get to the latest snapshot of the data
> >$sth->execute some select statement
> >
> >If the database connection has been closed because of a timeout, the 
> >commit will give an exception because of "mysql has gone away".
> >
> >I'm used to the behaviour (with non-transaction tables in mysql) 
> >that dbi/DBD::mysql reopens database connections transparently. This 
> >is not the case anymore, since now in some cases there will be an 
> >exception in others not. And I really didn't expect an exception in 
> >the above.
> >
> >I guess the above behaviour is because of the possibility of a case 
> >where you issue some statements without committing them, then the 
> >connection goes away, then you issue commit (maybe after another few 
> >statements), this would give problems.
> >
> >But dbi/dbd could handle my situation differently: if (and only if) 
> >the connection did go away *between two commits*, there is no reason 
> >to give an error. (To rephrase: If I issue some data modifying 
> >statements, do a commit (which succeeds), then the connection goes 
> >away, and I do another commit (for the sole purpose to get a recent 
> >snapshot), don't give an error since I won't expect it and won't 
> >know what to do with it.)
> >
> >Unless I'm missing something I would put this as a feature request. :)

I have something similar, with the same intent, in my to-do list.

> Thanks,
> Christian.
> 
> BTW I've played with the idea of subclassing DBI/DBI::db/DBI::st and 
> implementing the above thins myself by overriding all do/execute/et 
> al calls. But I guess it will be very slow since the object is a tied 
> hash and so putting my own flags in there will add even more 
> overhead. Out of curiosity: is there any reason a tied hash approach 
> for storing attributes has been choosen and not just accessor methods?

There will be hundreds of attributes before too long (ala ODBC GetInfo()).

Tim.

Reply via email to