Bug #76525 [Com]: mysqli::commit does not throw if MYSQLI_REPORT_ERROR enabled and mysqlnd used
| From: | dominik dot fiser at w3w dot cz | Date: | Thu, 13 Dec 2018 16:01:23 +0000 |
| Subject: | Bug #76525 [Com]: mysqli::commit does not throw if MYSQLI_REPORT_ERROR enabled and mysqlnd used | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-218432@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=76525&edit=1
ID: 76525
Comment by: dominik dot fiser at w3w dot cz
Reported by: willem at mollie dot nl
Summary: mysqli::commit does not throw if MYSQLI_REPORT_ERROR
enabled and mysqlnd used
Status: Open
Type: Bug
Package: MySQLi related
Operating System: Debian
PHP Version: 7.1.19
Block user comment: N
Private report: N
New Comment:
We have similar and probably related problem with Galera and mysql PDO.
Galera Cluster instead of standard MySQL/MariaDD could fail on commit query due to its replication
mechanism (described e.g. at https://www.percona.com/blog/2012/11/20/understanding-multi-node-writing-conflict-metrics-in-percona-xtradb-cluster-and-galera/).
We are using PPH 7.2.11 and mysql PDO with error mode PDO::ATTR_ERRMODE = PDO::ERRMODE_EXCEPTION.
That's really pain and very hard to find, if you are catching exceptions and there is no
exception, no error and transaction is not commited in database. This should be fixed ASAP.
Previous Comments:
------------------------------------------------------------------------
[2018-06-25 08:35:40] willem at mollie dot nl
Description:
------------
We experienced lost data because the mysqli::commit() function does not throw under some conditions
if mysqlnd is used. We configured mysqli to use report_mode = MYSQLI_REPORT_ERROR |
MYSQLI_REPORT_STRICT.
We use a MySQL Galera cluster setup and during reboots of nodes deadlocks in the commit query can
occur.
However, these deadlocks do not cause an exception to be thrown if the ::commit() method is used.
Instead, false is returned. In practice, the call fails silently.
Sending COMMIT queries manually works as expected (an exception is thrown on a dead lock).
You can see in https://github.com/php/php-src/blob/5f54f48024783df739dd5bbec64cb74063fefa06/ext/mysqli/mysqli_api.c#L741
that the error handling is missing for mysqlnd if you compare to https://github.com/php/php-src/blob/5f54f48024783df739dd5bbec64cb74063fefa06/ext/mysqli/mysqli_api.c#L1579.
I'd guess that the MYSQLI_REPORT_MYSQL_ERROR macro is missing.
Expected result:
----------------
If the commit() method encounters a "Deadlock found when trying to get lock; try restarting
transaction" error (1213 code), with report_mode = MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT
we expect it to throw mysqli_sql_exception.
Actual result:
--------------
False is returned, e.g. the report_mode is ignored.
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=76525&edit=1