From: fk at florian-kaiser dot net
Operating system: Debian Linux
PHP version: 5.5.8
Package: PDO MySQL
Bug Type: Bug
Bug description:No PDOException or errorCode if database becomes unavailable before PDO::commit
Description:
------------
If the database resource (e.g. the MySQL-Server) becomes unavailable
before a PDO::commit(), it emits a warning only, e.g. "MySQL server has
gone away" or "Error reading result set's header" and code execution
proceeds.
Additionally, neither PDO::errorCode() nor PDO::errorInfo() are set.
Inspected just after the warnings both suggest that everything is
perfectly fine. This is unacceptable.
I dont really like the handling of that situation at all. Since warnings
will only get logged in production mode and code execution proceeds
without knowing there actually was an error (happens with PDO::commit()
that returns true regardless), this will for sure give some developer
lots of headaches. Together with that other bug in PDO::commit(),
current implementation makes it _impossible_ to reliably check if a
PDO::commit() call failed.
Please note that using PDO::query('commit'); instead of PDO::commit()
actually respects PDO::ATTR_ERRMODE and behaves in a more proper way,
e.g. if set to PDO::ERRMODE_EXCEPTION actually throws a PDOException and
PDO::errorCode/errorInfo will be set accordingly. Warnings though will
show regardless (when you're on it, fix that as well, please).
This is the only workaround in current implementations to reliably use
transactions with PDOMysql.
A severe interruption like connection loss to database should be treated
with the same error handling that is used when establishing the
connection. Better still, just do it like PDO::query, honor
PDO::ATTR_ERRMODE or throw a PDOException per default. No matter what
will be implemented, PDO::errorCode and PDO::errorInfo must be fixed so
they reflect errors that occur when using PDO::commit().
Test script:
---------------
<?php
$dbh = new PDO('mysql:dbname=test;host=127.0.0.1;charset=UTF8',
'testuser', '');
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// prepare table for test
$dbh->query('DROP TABLE IF EXISTS importantdata');
$dbh->query('create table test.importantdata (a int) engine=innodb');
try {
$dbh->beginTransaction();
$dbh->query('insert into importantdata (a) VALUES (1), (2)');
sleep(20); // shut down mysql-server
$dbh->commit();
} catch (PDOException $e) {
exit($e->getMessage());
}
print_r($dbh->errorInfo());
echo 'I should never get here';
?>
Expected result:
----------------
"SQLSTATE[HY000]: General error: 2006 MySQL server has gone away"
[... Script execution stopped]
Actual result:
--------------
Warning: PDO::commit(): MySQL server has gone away in /tmp/test.php on
line 16
Warning: PDO::commit(): Error reading result set's header in
/tmp/test.php on line 16
Array
(
[0] => 00000
[1] =>
[2] =>
)
I should never get here
[... Script execution proceeds]
--
Edit bug report at https://bugs.php.net/bug.php?id=66528&edit=1
--
Try a snapshot (PHP 5.4): https://bugs.php.net/fix.php?id=66528&r=trysnapshot54
Try a snapshot (PHP 5.5): https://bugs.php.net/fix.php?id=66528&r=trysnapshot55
Try a snapshot (trunk): https://bugs.php.net/fix.php?id=66528&r=trysnapshottrunk
Fixed in SVN: https://bugs.php.net/fix.php?id=66528&r=fixed
Fixed in release: https://bugs.php.net/fix.php?id=66528&r=alreadyfixed
Need backtrace: https://bugs.php.net/fix.php?id=66528&r=needtrace
Need Reproduce Script: https://bugs.php.net/fix.php?id=66528&r=needscript
Try newer version: https://bugs.php.net/fix.php?id=66528&r=oldversion
Not developer issue: https://bugs.php.net/fix.php?id=66528&r=support
Expected behavior: https://bugs.php.net/fix.php?id=66528&r=notwrong
Not enough info: https://bugs.php.net/fix.php?id=66528&r=notenoughinfo
Submitted twice: https://bugs.php.net/fix.php?id=66528&r=submittedtwice
register_globals: https://bugs.php.net/fix.php?id=66528&r=globals
PHP 4 support discontinued: https://bugs.php.net/fix.php?id=66528&r=php4
Daylight Savings: https://bugs.php.net/fix.php?id=66528&r=dst
IIS Stability: https://bugs.php.net/fix.php?id=66528&r=isapi
Install GNU Sed: https://bugs.php.net/fix.php?id=66528&r=gnused
Floating point limitations: https://bugs.php.net/fix.php?id=66528&r=float
No Zend Extensions: https://bugs.php.net/fix.php?id=66528&r=nozend
MySQL Configuration Error: https://bugs.php.net/fix.php?id=66528&r=mysqlcfg