php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #77163 PDOException not thrown for SELECT FOR UPDATE with ATTR_EMULATE_PREPARES = 0
Submitted: 2018-11-15 12:28 UTC Modified: 2020-10-28 15:09 UTC
Votes:5
Avg. Score:4.0 ± 0.9
Reproduced:3 of 3 (100.0%)
Same Version:1 (33.3%)
Same OS:1 (33.3%)
From: contact at bastiaangrutters dot nl Assigned: nikic (profile)
Status: Closed Package: PDO MySQL
PHP Version: 7.4.5 OS: Linux
Private report: No CVE-ID: None
View Add Comment Developer Edit
Anyone can comment on a bug. Have a simpler test case? Does it work for you on a different platform? Let us know!
Just going to say 'Me too!'? Don't clutter the database with that please !
Your email address:
MUST BE VALID
Solve the problem:
36 - 20 = ?
Subscribe to this entry?

 
 [2018-11-15 12:28 UTC] contact at bastiaangrutters dot nl
Description:
------------
When using PDO MySQL to select rows for update with PDO::ATTR_EMULATE_PREPARES set to false and PDO::ATTR_ERRMODE set to PDO::ERRMODE_EXCEPTION no exception is thrown when the rows are already locked and a timeout occurs.

Note:
The exception is thrown when PDO::ATTR_EMULATE_PREPARES is not set/set to true or when a parameter is used in the select query.

Instructions on reproducing this: 
Open mysql on cli, and perform queries:
CREATE DATABASE testdb;
USE testdb;
CREATE TABLE test (`id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, `value` VARCHAR(30) NOT NULL);
INSERT INTO `test` (`value`) VALUES ('test');

# Before starting the test script open a transaction and lock the table:

BEGIN;
SELECT * FROM `test` FOR UPDATE;

# Now run the script

Test script:
---------------
<?php
$pdo = new PDO('mysql:dbname=testdb;host=localhost', 'username', 'password');
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$pdo->beginTransaction();
$statement = $pdo->prepare('SELECT * FROM `test` FOR UPDATE');

$statement->execute();

var_dump(
$statement->fetchAll(), 
$statement->errorCode()
);

$pdo->commit();


Expected result:
----------------
Fatal error: Uncaught PDOException: SQLSTATE[HY000]: General error: 1205 Lock wait timeout exceeded; try restarting transaction in test-pdo.php:14
Stack trace:
#0 test-pdo.php(14): PDOStatement->execute()
#1 {main} thrown in test-pdo.php on line 14

Actual result:
--------------
array(0) {
}
string(5) "00000"

Patches

Add a Patch

Pull Requests

Pull requests:

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-04-22 07:04 UTC] sjon@php.net
-Status: Open +Status: Verified -PHP Version: 7.2.12 +PHP Version: 7.4.5
 [2020-04-22 07:04 UTC] sjon@php.net
this is still broken
 [2020-09-01 11:19 UTC] cmb@php.net
The following pull request has been associated:

Patch Name: with ATTR_EMULATE_PREPARES = false, don't ignore deadlock errors
On GitHub:  https://github.com/php/php-src/pull/5937
Patch:      https://github.com/php/php-src/pull/5937.patch
 [2020-10-28 15:09 UTC] nikic@php.net
-Status: Verified +Status: Closed -Assigned To: +Assigned To: nikic
 [2020-10-28 15:09 UTC] nikic@php.net
This should be fixed by https://github.com/php/php-src/commit/b03776adb5bbb9b54731a44377632fcc94a59d2f for bug #79375 (with a large number of duplicates...)
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Apr 25 00:01:41 2024 UTC