Magento CE 1.9 – No Active Transaction During Checkout Registration

ce-1.9.0.1onepage-checkout

The problem started with a dialog / e-mail error showing up when new customers were trying to register an account at checkout.

I first started my troubleshooting by logging into authorize.net and found that customers continued to submit the order, it would come through multiple times, sometimes with a price and invoice number sometimes not. I would receive the error message e-mail but no customer or order would exist in the back end. I had to void those orders manually because they did not exist in magento.

I then went through a process of disabling extensions (going to modules and changing true to false) to troubleshoot the issue and this is what I've found knowing that none of my extensions seems to have an effect.

Guest Checkout is disabled.

  1. Only occurs when a customer registers a new account at check out. You can log in to an existing account or go to the register page and create a new account with no problem.

  2. I have paradoxlabs Authorize.net CIM extension. I disabled it and tested with Magentos Authorize.net extension and received the same result. I tried checking out with PayPal and was not able to redirect to the paypal site.

  3. I enabled PO as a payment method and that does work.

  4. The URL I get stuck at is checkout/onepage/?register

  5. Sometimes the order posts to authorize.net sometimes it doesn't. Either way it never shows up in the backend.

I checked the exceptions log and found this. (removed full path for privacy)

2015-03-23T04:54:01+00:00 ERR (3): 
exception 'PDOException' with message 'There is no active transaction' in /lib/Zend/Db/Adapter/Pdo/Abstract.php:322
Stack trace:
#0 /lib/Zend/Db/Adapter/Pdo/Abstract.php(322): PDO->rollBack()
#1 /lib/Zend/Db/Adapter/Abstract.php(524): Zend_Db_Adapter_Pdo_Abstract->_rollBack()
#2 /lib/Varien/Db/Adapter/Pdo/Mysql.php(258): Zend_Db_Adapter_Abstract->rollBack()
#3 /app/code/core/Mage/Core/Model/Resource/Abstract.php(124): Varien_Db_Adapter_Pdo_Mysql->rollback()
#4 /app/code/core/Mage/Core/Model/Resource/Transaction.php(92): Mage_Core_Model_Resource_Abstract->rollBack()
#5 /app/code/core/Mage/Core/Model/Resource/Transaction.php(166): Mage_Core_Model_Resource_Transaction->_rollbackTransaction()
#6 /app/code/core/Mage/Sales/Model/Service/Quote.php(189): Mage_Core_Model_Resource_Transaction->save()
#7 /app/code/core/Mage/Sales/Model/Service/Quote.php(249): Mage_Sales_Model_Service_Quote->submitOrder()
#8 /app/code/core/Mage/Checkout/Model/Type/Onepage.php(784): Mage_Sales_Model_Service_Quote->submitAll()
#9 /app/code/core/Mage/Checkout/controllers/OnepageController.php(579): Mage_Checkout_Model_Type_Onepage->saveOrder()
#10 /app/code/core/Mage/Core/Controller/Varien/Action.php(418): Mage_Checkout_OnepageController->saveOrderAction()
#11 /app/code/core/Mage/Core/Controller/Varien/Router/Standard.php(250): Mage_Core_Controller_Varien_Action->dispatch('saveOrder')
#12 /app/code/core/Mage/Core/Controller/Varien/Front.php(172): Mage_Core_Controller_Varien_Router_Standard->match(Object(Mage_Core_Controller_Request_Http))
#13 /app/code/core/Mage/Core/Model/App.php(354): Mage_Core_Controller_Varien_Front->dispatch()
#14 /app/Mage.php(684): Mage_Core_Model_App->run(Array)
#15 /index.php(87): Mage::run('', 'store')
#16 {main}

I seem to be stuck as I don't know what to do next. I asked the company that made my theme to look at it and they said to ask Paradox, which I already did and they suggested it was an extension or other issue.

Best Answer

I hit this issue today, and went digging to find the problem.

If anyone hits the issue with "PDO - There is no active Transaction" on Magento, it is caused by having another call of save() from any other model inside a _beforeSave() or _afterSave() methods or from any save_before or save_after observers.

Theoretically, the second save() call will issue a COMMIT on success, or a ROLLBACK on failure, and it will end the first transaction too.

By the time the first model starts the COMMIT, it will fail, and will attempt to ROLLBACK, which will also fail, as the first transaction was already commited or rolledback.

I say theoretically, because Varien_Db_Adapter_Pdo_Mysql keeps track of transactions depth, and only will fully commit or rollback based on the first transaction.

public function beginTransaction()
{
    if ($this->_transactionLevel === 0) {
        $this->_debugTimer();
        parent::beginTransaction();
        $this->_debugStat(self::DEBUG_TRANSACTION, 'BEGIN');
    }
    ++$this->_transactionLevel;
    return $this;
}

public function commit()
{
    if ($this->_transactionLevel === 1) {
        $this->_debugTimer();
        parent::commit();
        $this->_debugStat(self::DEBUG_TRANSACTION, 'COMMIT');
    }
    --$this->_transactionLevel;
    return $this;
}

The weird stuff is that was not working... The $_transactionLevel did went up to 1, and the commit was properly called with $_transactionLevel at value of 1, but it yet raised the error.

In my case I had a model that worked with a collection of other items. When I needed to save the model, I first needed to save all items from the collection, and then proceed to the model save.

I was doing that from the _beforeSave() hook, and that raised the "PDO - There is no active transaction" by the time the model was being commited.

I did solve my issue separating the save calls, creating a method to purely save the collection, and then save the model itself.

Soon I realized that there was something wrong with that... I needed to serialize some model data before saving to the DB, and noticed that during the process of serialization my collection was being serialized too.

It was indeed my blame, since I forgot to declare a property and the collection was being stored inside the $_data property.

When the collection was serialized, it did serialize the DB connection model. That may have triggered the issue.

Once I declared the property, I could go back to hook on _beforeSave(), as the collection items are stored on the DB in another table.

Hope the answer shows some clarification for future visitors.

  • Avoid serialization of DB collections;
  • If that is truly needed, encapsulate your save methods in distinct functions.