Bug #66529 [Opn]: PDO::commit returns true on failure
| From: | mbeccati@php.net | Date: | Mon, 03 Nov 2014 08:28:21 +0000 |
| Subject: | Bug #66529 [Opn]: PDO::commit returns true on failure | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-188426@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=66529&edit=1
ID: 66529
Updated by: mbeccati@php.net
Reported by: fk at florian-kaiser dot net
Summary: PDO::commit returns true on failure
Status: Open
Type: Bug
-Package: PDO Core
+Package: PDO MySQL
Operating System: Debian Linux
PHP Version: 5.5.8
Block user comment: N
Private report: N
New Comment:
Seems to be mysql-only. With PDO_pgsql I got:
PHP Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY000]:
General error: 7 server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.'
Previous Comments:
------------------------------------------------------------------------
[2014-01-21 10:16:25] fk at florian-kaiser dot net
Description:
------------
When you use PDO::beginTransaction(), do a query and issue PDO::commit(), the result of the last
call is bogus at best.
Documentation states "Returns TRUE on success or FALSE on failure.". In current
implementation, this is wrong. In fact, it returns TRUE in all cases I tested - even for
_impossible_ commits. The only time it actually fails is when issuing a PDO::commit() while no
transaction is active. This will, regardless of what you set PDO::ATTR_ERRMODE to, result in a
PDO::EXCEPTION (that is another bug, see #63546).
Unfortunately, there is another bug in the implementation of PDO::commit() that makes it almost
impossible to detect that error since "MySQL server has gone away" or "Error reading
result set's header" are only issued as as warnings and neither PDO::errorCode() nor
PDO::errorInfo() are set, nor is a PDOException thrown. PDO_ATTR_ERRMODE is also not beeing honored.
I filed that bug under #66528 and will only focus on the bug described above in this report.
The easiest way to reproduce is to start a transaction, issue a query, sleep for a couple of seconds
and while doing that, shutting down the MySQL-Server. When the server is clearly gone, issue
PDO::commit(). Although PDO knows it can under no circumstances have commited the data, it returns
success for the operation.
Test script:
---------------
<?php
$dbh = new PDO('mysql:dbname=test;host=127.0.0.1;charset=UTF8', 'testuser',
'');
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
// prepare table for test
$dbh->query('DROP TABLE IF EXISTS importantdata');
$dbh->query('create table test.importantdata (a int) engine=innodb');
$dbh->beginTransaction();
$dbh->query('insert into importantdata (a) VALUES (1), (2)');
sleep(20); // shut down mysql-server
var_dump($dbh->commit());
?>
Expected result:
----------------
bool(false)
Actual result:
--------------
bool(true)
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=66529&edit=1