php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #57037 Need a way to read current transaction state
Submitted: 2006-05-24 13:38 UTC Modified: 2015-04-07 18:50 UTC
From: hans at velum dot net Assigned: cmb (profile)
Status: Closed Package: *General Issues
PHP Version: 5.1.0 OS: n/a
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: hans at velum dot net
New email:
PHP Version: OS:

 

 [2006-05-24 13:38 UTC] hans at velum dot net
Description:
------------
I am rewriting the Propel ORM framework to use PDO (instead of Creole) as the runtime database abstraction layer.  In doing so, I have come accross a need (which I'm sure is shared by others using PDO in frameworks) for the ability to determine whether a transaction has already been started for a particular PDO object.

The basic problem is that I have nested code using transactions.  Of course eventually, support for nested transactions would be nice for the databases that support it, but in the meantime it would be great if I could programmatically determine whether a connection had been started and avoid the PDOException being thrown when I attempt to beginTransaction() in mid-transaction.

E.g. something like this would make life easier:

$usetx = !$con->isInTransaction();

try {
 if ($usetx) $con->beginTransaction();
 /* db operations here */
 if ($usetx) $con->commit();
} catch (Exception $e) {
  if ($usetx) $con->rollback();
  throw $e;
}


Reproduce code:
---------------
function save($con) 
  $con->beginTransaction();
  insert($con);
  insertRelated($con);
  $con->commit();
}

function insert($con) {
  $con->beginTransaction(); // PDOException when called from save()
  $con->exec("INSERT....");
  $con->exec("INSERT....");
  $con->exec("INSERT....");
  $con->commit();
}



Expected result:
----------------
Ability to check for transaction in nested insert() function and hence avoid PDOException.

Actual result:
--------------
PDOException

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-06-29 14:20 UTC] hans at velum dot net
If PDO plans to support nested transactions, then perhaps $con->getTransactionOpcount() or $con->getNestedTransactionCount() would be a better choice for determining whether a transaction is in-progress.
 [2006-07-21 17:26 UTC] bugs at xmlnode dot com
I also have a need to know if PDO is in a transaction.  

I was able to find in_txn in the PDO sources, but it's not publically accessible.  I also tried to call beginTransaction() twice or commit() without having called beginTransaction() and PDO knows whether or not it's in a transaction, it would just be nice to have the state publically accessbile.

As an aside, if ATTR_ERRMODE is used to receive PDO errors as warnings, and you call beginTransaction() twice or call commit() without having called beginTransaction() PDO throws an exception, which is contrary to how I understood ATTR_ERRMODE worked.  It's not a big issue, just thought I'd mention it.
 [2006-10-18 05:33 UTC] michael dot walte at gmail dot com
Unrelated to the actual request, you should not call beginTransaction() inside the "try {..}" body.
 [2007-10-24 07:49 UTC] cameron dot brunner at gmail dot com
+1
 [2007-10-24 08:18 UTC] heltem at o2php dot com
Need this nested transaction support in PDO too.
+1
 [2007-10-24 09:37 UTC] felix dot gilcher at exozet dot com
+1 - we depend on this feature as well.
 [2007-10-24 18:34 UTC] devzie at gmail dot com
+1 we need this feature too
 [2007-10-24 19:02 UTC] weinberg dot jon at gmail dot com
+1, this would be very nice to have.
 [2007-10-24 19:52 UTC] wez@php.net
Please stop spamming the ticket; updating it over and over again isn't going to make it happen any faster.
 [2007-12-06 18:27 UTC] phil at webstarsltd dot com
Isn't this exactly the kind of situation object extension is meant for?

Until such time as PDO offers this natively you could use a sub-class that exposes a method inTransaction(), then override the transaction methods to update this value, then calling the parent to actually carry out the function.

Am I missing something here (like horrendous performance penalty by sub-classing built-in PHP objects)?
 [2007-12-14 14:55 UTC] hans at velum dot net
Re: Phil's comment.

Yes, that is currently what we (Propel) are doing; however, I would argue that this is something that belongs in the core functionality.

Subclassing works great when only your project needs to use the PDO object; however, when you want to build code that inter-operates with other libraries you run into trouble.  For example, if you want to use a PDO connection created by Zend_DB in Propel, you're out of luck because Propel requires PropelPDO.

At least making this exception suppressable by config option would go a huge way to making PDO usable in a framework context.
 [2015-04-07 18:50 UTC] cmb@php.net
-Status: Open +Status: Closed -Package: PDO +Package: *General Issues -Assigned To: +Assigned To: cmb
 [2015-04-07 18:50 UTC] cmb@php.net
Thank you for your bug report. This issue has already been fixed
in the latest released version of PHP, which you can download at 
http://www.php.net/downloads.php

As of PHP 5.3.3 PDO::inTransaction() is available.
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Sat Jul 12 13:01:33 2025 UTC