Reading list Switch to dark mode

    Working With Database Transactions In Magento2

    Updated 6 March 2024

    Introduction

    In a structure like magento2, it is very difficult to guarantee the consistency of data, the system of EAV(Entity Attribute Value) makes magento2 highly scalable and modular but every thing comes with a cost, managing the data in these structures can be very difficult. To ensure the consistency of data, magento2 uses database transactions.

    Whenever we save a model in Magento, it gets executed as a transaction, when you will dig deeper and check the Magento\Framework\Model\AbstractModel class you will found the save function:

    public function save()
        {
            $this->_getResource()->save($this);
            return $this;
        }

    you can see that the save method is calling another save method from resource class, even the delete method calls the delete method of the resource model class, so resource model is responsible for saving, updating, deleting rows from the database.

    Let’s check the resource model save method when you will check the resource model parent class, you will find this class:

    Magento\Framework\Model\ResourceModel\Db\AbstractDb and the save method is defined in the class, although you can override the save method in the resource model concrete class, you still need to call the parent class “save” method:

    Searching for an experienced
    Magento 2 Company ?
    Find out More
    public function save(\Magento\Framework\Model\AbstractModel $object)
        {
            if ($object->isDeleted()) {
                return $this->delete($object);
            }
    
            $this->beginTransaction();
    
            try {
                if (!$this->isModified($object)) {
                    $this->processNotModifiedSave($object);
                    $this->commit();
                    $object->setHasDataChanges(false);
                    return $this;
                }
                $object->validateBeforeSave();
                $object->beforeSave();
                if ($object->isSaveAllowed()) {
                    $this->_serializeFields($object);
                    $this->_beforeSave($object);
                    $this->_checkUnique($object);
                    $this->objectRelationProcessor->validateDataIntegrity($this->getMainTable(), $object->getData());
                    if ($this->isObjectNotNew($object)) {
                        $this->updateObject($object);
                    } else {
                        $this->saveNewObject($object);
                    }
                    $this->unserializeFields($object);
                    $this->processAfterSaves($object);
                }
                $this->addCommitCallback([$object, 'afterCommitCallback'])->commit();
                $object->setHasDataChanges(false);
            } catch (DuplicateException $e) {
                $this->rollBack();
                $object->setHasDataChanges(true);
                throw new AlreadyExistsException(new Phrase('Unique constraint violation found'), $e);
            } catch (\Exception $e) {
                $this->rollBack();
                $object->setHasDataChanges(true);
                throw $e;
            }
            return $this;
        }

    The above code is also very abstract, but still pretty much understandable, thanks to great naming sense by the Magento developers. The methods those are related to transactions are:

    • beginTransaction: this method starts the transaction.
    • commit: this method commits the transaction, we should only call the commit until and unless it is assured that everything is correct because there is no rolling back after commit.
    • rollBack: this is used to roll back all the changes in the tables if any exception arises, as you can see it is called in the catch block of exception handling.

    the above save method could be similar to the raw SQL code:

    START TRANSACTION
    
    //multiple queries can be defined here to save or update the database tables
    
    COMMIT or ROLLBACK

    That’s how Magento uses transactions while you save or update any models. you can even create an observer to make some checks before commit and if your check fails just throw an error and every thing will be rolled back.

    If you check the function processAfterSaves:

    protected function processAfterSaves(\Magento\Framework\Model\AbstractModel $object)
        {
            $this->_afterSave($object);
            $object->afterSave();
        }

    in the above method, you can see the object’s(this object can be any model class) afterSave method is called, the afterSave method of model resides in class Magento\Framework\Model\AbstractModel\

    public function afterSave()
        {
            $this->cleanModelCache();
            $this->_eventManager->dispatch('model_save_after', ['object' => $this]);
            $this->_eventManager->dispatch('clean_cache_by_tags', ['object' => $this]);
            $this->_eventManager->dispatch($this->_eventPrefix . '_save_after', $this->_getEventData());
            $this->updateStoredData();
            return $this;
        }

    in the above method you can see there is an event dispatched, with a dynamic string included in the name:

    $this->_eventPrefix this returns the model’s events prefix name that you define in your model class, in the case of order model it is sales_order, so the after saving event for the order model will be:

    sales_order_after_save similarly you can predict any model class after save observer event name. Using this event you can put your code before commit and can easily roll back any incorrect updates.

    Hope this will help you in solving your issues. If you have any issues or doubts in the above explanation you can ask in the comments, I will try my best to answer you.

    Thanks 🙂

    . . .

    Leave a Comment

    Your email address will not be published. Required fields are marked*


    Be the first to comment.

    Back to Top

    Message Sent!

    If you have more details or questions, you can reply to the received confirmation email.

    Back to Home