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
 [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

Add a Patch

Pull Requests

Add a Pull Request

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-2024 The PHP Group
All rights reserved.
Last updated: Wed Apr 24 02:01:30 2024 UTC