Subject Re: [firebird-php] Proper transaction & deadlock handling
Author Daniel Miller
You're absolutely right - the commit was missing from the sample I
uploaded - though it should be present in all my active code. Revised block:

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() );
}

if (!ibase_commit( $th )) {
throw new Exception( "Failed to update status for $node " .
ibase_errmsg() );
}

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

I was having issues with the implicit transactions - so I changed to
explicit transactions with explicit commits, with mostly READ flags,
throughout.

Daniel

On 11/21/2016 1:19 AM, masotti masotti@... [firebird-php] wrote:
> Hi!
>
> I don't see in your code explicit commit or rollback (ibase_commit(),
> ibase_rollback()).
>
> This means that implicit commit is done at end of script, when you've no
> chance to test anything.
>
> My personal PHP WEB programming view, has all implicit only READ
> transactions through pooled connection, and only when strictly needed
> open a WRITE transaction and commit (or rollback) ASAP in code.
> This, AFAIU, the first time create a new pooled commection with WRITE
> characteristics (from WEB server to Firebird Server), and subsequent
> WRITE transactions call reuse that already opened connection.
>
> Hope this helps.
>
> MM
>
>
> Il 20/11/2016 06:30, Daniel Miller dmiller@... [firebird-php] ha
> scritto:
>>
>> 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
>
> ------------------------------------
> Posted by: masotti <masotti@...>
> ------------------------------------
>
>
> ------------------------------------
>
> Yahoo Groups Links
>
>
>