Subject Re: [firebird-php] Transactions with prepared statements CRASH.
Author Lester Caine
Stan wrote:
> Hi All,
>
> The following code snippet causes PHP to crash
> inside gds32.dll in one of the ibase_execute calls,
> debugger is showing isc_dsql_execute2()...
>
> This happens only when there is a lock-conflict,
> so one client runs perfectly, while 2 clients
> will always crash PHP!
>
> I am using:
> Apache 2.0.54
> PHP 5.1.6
> Windows XP Pro
> Firebird 1.5.3
>
> I tried using the gds32.dll that came with PHP
> as well as the one that comes with (instclient i g) Firebird 1.5.3,
> both crash.
The one supplied with PHP should be ignored, just use the current client
that goes with your client

> I tried using PHP as an Apache module as well as a CGI, both
> crash, so it is not a thread-safety issue.
>
> The code works great if I do NOT use prepared statements,
> but I want the speed improvement.
>
> The code does not crash if I do not use explicit transaction handling,
> but this causes incorrect behavior for my app.
>
> in the Apache log I get:
> -501 Attempt to reclose a closed cursor
> from the ibase_execute() call, why?
>
> what am I doing wrong?
>
> thanks,
>
> stan
>
> code snippet:
> ------------------------------------------------------------------
> $db = ibase_connect (...);
> $trans = ibase_trans($db, IBASE_WRITE|IBASE_CONCURRENCY|IBASE_WAIT);
try IBASE_REC_VERSION | IBASE_COMMITTED when using IBASE_WRITE
IBASE_CONCURRENCY is more consistent with IBASE_READ since it provides a
SNAPSHOT view of the data
> $stmt = ibase_prepare($trans, "SELECT id FROM GET_ID(?,?,?)");
>
> foreach($entries as $entry){
> $res = ibase_execute( $stmt, $entry[0], $enty[1], $entry[2]);
>
> if( !$res) {
> // lock conflict
> // commit all changes thus far
> ibase_commit($trans);
> ibase_free_query($stmt);
>
> // re-start transaction
> $trans = ibase_trans($db, IBASE_WRITE|IBASE_CONCURRENCY|IBASE_WAIT);
>
> // re-prepare the statement
> $stmt = ibase_prepare($trans, "SELECT id FROM GET_ID(?,?,?)");
>
> // re-run the query, this time it should always succeed
> $res = ibase_execute( $stmt, $entry[0], $enty[1], $entry[2]);
>
> assert($res)
>
> // fetch the data ...
> }
> }
>
> // commit all changes
> ibase_commit($trans);
> ibase_free_query($stmt);
> ibase_close($db);
> ----------------------------------------------


--
Lester Caine - G8HFL
-----------------------------
L.S.Caine Electronic Services - http://home.lsces.co.uk
Model Engineers Digital Workshop -
http://home.lsces.co.uk/ModelEngineersDigitalWorkshop/
Treasurer - Firebird Foundation Inc. - http://www.firebirdsql.org/index.php