php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #67462 PDO_PGSQL::beginTransaction() wrongly throws exception when not in transaction
Submitted: 2014-06-17 11:57 UTC Modified: 2014-10-31 16:44 UTC
From: piotr dot m at shwrm dot com Assigned: mbeccati
Status: Closed Package: PDO PgSQL
PHP Version: 5.5.13 OS: *
Private report: No CVE-ID:
 [2014-06-17 11:57 UTC] piotr dot m at shwrm dot com
Description:
------------
PDOConnection->inTransaction() combined with PostgreSQL seems to return false after a failed commit exception is caught by the try/catch block. 

This problem seems to occur both in CLI mode and when called via FPM.

One more bit of information: the DB constraint that causes the duplicate key exception is in "DEFERRABLE INITIALLY DEFERRED" mode so it will be checked after COMMIT is called, not immediately after an update statement is executed. 

PHP: 5.5.13-1~dotdeb.1 (both FPM and CLI)
Postgresql: "PostgreSQL 9.3.4 on x86_64-unknown-linux-gnu, compiled by gcc (Debian 4.7.2-5) 4.7.2, 64-bit"


Test script:
---------------
$con = new \PDO('pgsql:host=127.0.0.1;port=5432;dbname=;user=;password=');
$con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$con->beginTransaction();

$prod = $con->prepare(/** QUERY THAT CAUSES SQLSTATE[23505]: Unique violation: 7 ERROR:  duplicate key value**/);
$prod->execute();

try {
	var_dump($con->inTransaction());
	$con->commit();
} catch (\Exception $e) {
	var_dump($con->inTransaction());
	$con->inTransaction() or $con->beginTransaction();
}

Expected result:
----------------
bool(true)
bool(true)


Actual result:
--------------
bool(true)
bool(false)
PHP Fatal error:  Uncaught exception 'PDOException' with message 'There is already an active transaction' in ...

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2014-10-31 16:44 UTC] mbeccati@php.net
-Summary: Postgres/PDO inTransaction() returns false while transaction is still active. +Summary: PDO_PGSQL::beginTransaction() wrongly throws exception when not in transaction -Status: Open +Status: Analyzed -Operating System: Linux/Ubuntu 14.04 +Operating System: * -Assigned To: +Assigned To: mbeccati
 [2014-10-31 16:44 UTC] mbeccati@php.net
The expected result is wrong. It should be:

bool(true)
bool(false)

as in:

regression=# begin; create table t (a int not null primary key deferrable initially deferred); insert into t values (1), (1);
BEGIN
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "t_pkey" for table "t"
CREATE TABLE
INSERT 0 2
regression=# commit;
ERROR:  duplicate key value violates unique constraint "t_pkey"
DETAIL:  Key (a)=(1) already exists.
regression=# rollback;
NOTICE:  there is no transaction in progress
ROLLBACK


However, no PDOException "There is already an active transaction" should be raised.
 [2014-10-31 18:00 UTC] mbeccati@php.net
Automatic comment on behalf of mbeccati
Revision: http://git.php.net/?p=php-src.git;a=commit;h=9580fcfeddf85f6510217fec2f596f6f5169f251
Log: Fixed bug #67462 PDO_PGSQL::beginTransaction() wrongly throws exception when not in transaction
 [2014-10-31 18:00 UTC] mbeccati@php.net
-Status: Analyzed +Status: Closed
 [2014-11-18 20:34 UTC] ab@php.net
Automatic comment on behalf of mbeccati
Revision: http://git.php.net/?p=php-src.git;a=commit;h=9580fcfeddf85f6510217fec2f596f6f5169f251
Log: Fixed bug #67462 PDO_PGSQL::beginTransaction() wrongly throws exception when not in transaction
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Sun Jul 23 02:01:35 2017 UTC