Subject | Proper transaction & deadlock handling |
---|---|
Author | Daniel Miller |
Post date | 2016-11-20T05:30:58Z |
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
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