Magento 2 - Транзакция базы данных для нескольких объектов модели / модели ресурсов?

11

Если у меня есть логика, которая включает обновление нескольких объектов модели, которые обновят несколько таблиц в базе данных, как обеспечить транзакцию базы данных для обеспечения целостности данных?

Павел
источник

Ответы:

22

Вы, вероятно, сохраняете совокупность нескольких связанных объектов. Определите, какой из этих объектов является корневым , например:

               [order]              <------ this is the root
               /  |  \
billing_address   |   shipping_address
                  |
            order_items

Добавьте логику обновления в модель ресурса корня и используйте транзакцию там.

Как использовать транзакции

  1. Если вы хотите сохранить несколько экземпляров модели, вы можете использовать модель транзакции. Вставьте фабрику транзакций \Magento\Framework\DB\TransactionFactoryв вашу модель ресурсов и используйте ее следующим образом:

    $saveTransaction = $this->transactionFactory->create();
    $saveTransaction->addObject($objectToSave);
    $saveTransaction->addObject($otherObjectToSave);
    ...
    $saveTransaction->save();
    

    Фиксация или откат автоматически обрабатываются save()методом.

  2. В качестве альтернативы вы можете использовать транзакции напрямую (если вы используете другие обновления базы данных, кроме $model->save():

    $connection = $this->getConnection();
    $connection->beginTransaction();
    try {
        ...
        $connection->commit();
    } catch (\Exception $e) {
        $connection->rollBack();
        throw $e;
    }
    
Фабиан Шменглер
источник
Есть ли какой-либо поддерживаемый способ сохранения нескольких объектов при использовании репозиториев? Они внутренне вызывают save()методы моделей ресурсов, поэтому каждая из них будет сохранена в отдельных транзакциях. Хранилища часто содержат некоторую логику проверки, поэтому обычно рекомендуется использовать их вместо save()методов модели простых ресурсов .
Бартош Кубицки
1
@BartoszKubicki есть. Если две модели ресурсов используют одно и то же соединение (которое обычно используется по умолчанию), сохранение отношения в afterSave () первого ресурса вызовет добавление запросов к одной и той же транзакции. Посмотрите, как заказы сохраняются, строка за строкой. OrderRepository :: save () является точкой входа.
vitoriodachef