Re: table locking with forking

Baron Schwartz <[email protected]> Wed, 19 Sep 2007 07:16:54 -0400
Newsgroups gmane.comp.db.mysql.perl
Message-ID <[email protected]>
Hi Jeremy,

Jeremy Kister wrote:
> I'm having issues with locking and forking code.  I've consolidated the 
> problem into the below example code.
> 
> I expect the parent to start, lock the table, and spawn the child.  I 
> then expect the child to die without inserting data, because the parent 
> had the table locked longer than the child was allowed to wait.  The 
> parent should then say "count: 0" and exit.
> 
> But instead, the child spawns, waits for the parent to unlock (ignoring 
> the alarm?), and inserts the data.
> 
> What do I have to do to change the behavior so that the child times out 
> and immediately stops trying to insert the data after a specified time 
> period ?
> 
> my $dbh = DBI->connect($dsn, $dbun, $dbpw, {RaiseError => 1});

I think you need to set InactiveDestroy here.  Setting it after the fork 
is probably too late.

> 
> $dbh->do('DELETE FROM table1 WHERE field1 > 1');
> $dbh->do('LOCK TABLE table1 READ');
> my $pid = fork();
> if($pid){
>    print "PARENT: starting.\n";
>    foreach(1..5){
>       print "PARENT: sleeping [$_/5]\n";
>       sleep 1;
>    }
>    $dbh->do('UNLOCK TABLES');
>    print "PARENT: exiting.\n";
> 
>    my $sql = 'SELECT COUNT(*) FROM table1 WHERE field1 = 5';
>    my $sth = $dbh->prepare($sql);
>    $sth->execute;
>    my $row = $sth->fetchrow_arrayref;
>    print "PARENT: count $row->[0]\n";
> 
> }else{
>    print "CHILD: starting.\n";
>    $dbh->{InactiveDestroy} = 1; # dont kill the parent $dbh
> 
>    eval {
>       local $SIG{ALRM} = sub { die "timeout."; };
>       alarm(3);
>       my $dbh = DBI->connect($dsn, $dbun, $dbpw, {RaiseError => 1});
>       print "CHILD: db connection succeeded\n";
> 
>       my $sql = 'INSERT INTO table1 (field1) VALUES (5)';
>       my $sth = $dbh->prepare($sql);
>       $sth->execute;
> 
>       print "CHILD: inserted data.\n";
>       alarm(0);
>    };
>    alarm(0);
>    if($@){
>       print "CHILD: $@\n";
>    }
>    print "CHILD: exiting.\n";
> }
> 

-- 
MySQL Perl Mailing List
For list archives: http://lists.mysql.com/perl
To unsubscribe:    http://lists.mysql.com/[email protected]