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.

(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. :)

)

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?
-- 
Christian Jaeger  Programmer & System Engineer  +41 1 430 45 26
ETHLife CMS Project - warehouse.ch/ethlife/www - www.ethlife.ethz.ch

Reply via email to