Bug #66528 [Opn]: No PDOException or errorCode if database becomes unavailable before PDO::commit
| From: | cmb@php.net | Date: | Sun, 28 Apr 2019 13:54:31 +0000 |
| Subject: | Bug #66528 [Opn]: No PDOException or errorCode if database becomes unavailable before PDO::commit | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-220632@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=66528&edit=1
ID: 66528
Updated by: cmb@php.net
Reported by: fk at florian-kaiser dot net
Summary: No PDOException or errorCode if database becomes
unavailable before PDO::commit
Status: Open
Type: Bug
Package: PDO MySQL
Operating System: Debian Linux
PHP Version: 7.3
Block user comment: N
Private report: N
New Comment:
Something like the commit-einfo patch would set the error info for
commits, but rollbacks and autocommits and maybe more seem to need
an analogous fix.
Wrt. additional warnings: I'm not sure how to handle these. Maybe
mysqlnd shouldn't raise them in the first place.
Previous Comments:
------------------------------------------------------------------------
[2019-04-28 13:50:38] cmb@php.net
The following patch has been added/updated:
Patch Name: commit-einfo
Revision: 1556459438
URL: https://bugs.php.net/patch-display.php?bug=66528&patch=commit-einfo&revision=1556459438
------------------------------------------------------------------------
[2019-04-27 14:44:17] fk at florian-kaiser dot net
Any news on this? Bug is still present in latest PHP 7.3, it's really time this gets fixed.
What can we do to speed this up?
------------------------------------------------------------------------
[2019-03-16 15:55:38] jonathan dot lopes at educlever dot com
The same lack of PDOException or error is visible for a conflict resolution on the PDO::COMMIT in a
galera environment : no "Deadlock found when trying to get lock; try restarting
transaction" feedback.
------------------------------------------------------------------------
[2017-07-20 21:05:07] fk at florian-kaiser dot net
It's now over 3 years since my initial bug report. Bug is still present in latest PHP7.1 making
it _impossible_ to use PDO::commit() in a reliable fashion.
I really don't understand why a bug this severe is being kept open this long. It would really
help us developers if this gets fixed soon.
------------------------------------------------------------------------
[2014-01-21 10:09:04] fk at florian-kaiser dot net
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 this bug report at https://bugs.php.net/bug.php?id=66528&edit=1