Subject Proper transaction & deadlock handling
Author Daniel Miller
Hi!

I'm not asking what a deadlock is, or why it happens. I'm not even
asking how to avoid them. I'm asking how to handle them properly with
Firebird & PHP - because I'm not finding documentation for it.

All my calls (I think!) to ibase_query() are prefaced by ibase_trans(),
and my standard options are

IBASE_READ|IBASE_COMMITTED|IBASE_REC_VERSION

or IBASE_WRITE if appropriate.

It's possible that my deadlock issues will go away now...as I just
changed the flags from using '+' to '|'. Oops. However...I'm obviously
not understanding something. The following is typical of my Firebird
PHP code:

try {
$th = ibase_trans( $this->dbh,
IBASE_WRITE|IBASE_COMMITTED|IBASE_REC_VERSION );
if ( !$th ) {
throw new Exception( 'Unable to create new transaction
because: ' . ibase_errmsg(), ibase_errcode() );
}

$qs = "update or insert into NODES (NODE) values ($node)
matching (NODE)";
$qh = ibase_query( $th, $qs );
if ( $qh === false ) {
throw new Exception( "Failed to update node $node " .
ibase_errmsg() );
}

return $qh;
} catch (Exception $e) {
echo "Caught exception: $e\n";
return false;
}

Now...I would have though that between checking the return values of
both ibase_trans() and ibase_query(), or by enclosing in a try/catch
block, I would be able to at least see the conflict. But that doesn't
happen. All I get is via stderr:

PHP Warning: ibase_query(): deadlock update conflicts with concurrent
update concurrent transaction number is 13403

So...if the above code construct isn't able to trap the deadlock - what
would?

--
Daniel