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
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: contact at bastiaangrutters dot nl
New email:
PHP Version: OS:

 

 [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

Pull Requests

Pull requests:

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: Sat Dec 21 13:01:31 2024 UTC