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.
Best Answer
i think it is the latest issue in magento.
please refer to this. https://magento.com/security/patches/supee-9767
and this. SUPEE-9767 Patch/CE 1.9.3.3 - One Page Checkout - Customer Registration issue