|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
Patchescommit-einfo (last revision 2019-04-28 13:50 UTC by cmb@php.net)Pull RequestsHistoryAllCommentsChangesGit/SVN commits
[2017-07-20 21:05 UTC] fk at florian-kaiser dot net
[2019-03-16 15:55 UTC] jonathan dot lopes at educlever dot com
[2019-04-27 14:44 UTC] fk at florian-kaiser dot net
-PHP Version: 5.5.8
+PHP Version: 7.3
[2019-04-27 14:44 UTC] fk at florian-kaiser dot net
[2019-04-28 13:50 UTC] cmb@php.net
[2019-04-28 13:54 UTC] cmb@php.net
[2020-10-28 09:00 UTC] nikic@php.net
-Assigned To:
+Assigned To: nikic
[2020-10-28 11:19 UTC] nikic@php.net
[2020-10-28 11:19 UTC] nikic@php.net
-Status: Assigned
+Status: Closed
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Wed Oct 29 23:00:01 2025 UTC |
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]