Magento 2 - Transaction de base de données pour plusieurs objets de modèle / modèle de ressource?

11

Si j'ai une logique qui implique la mise à jour de plusieurs objets de modèle qui mettront à jour quelques tables dans la base de données, comment fournir une transaction de base de données pour garantir l'intégrité des données?

Paul
la source

Réponses:

22

Vous enregistrez probablement un agrégat de plusieurs objets connectés. Déterminez lequel de ces objets est la racine , par exemple:

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

Ajoutez la logique de mise à jour dans le modèle de ressource de la racine et utilisez-y une transaction.

Comment utiliser les transactions

  1. Si vous souhaitez enregistrer plusieurs instances de modèle, vous pouvez utiliser le modèle de transaction. Injectez une fabrique de transactions \Magento\Framework\DB\TransactionFactorydans votre modèle de ressource et utilisez-la comme ceci:

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

    La validation ou la restauration est automatiquement gérée par la save()méthode.

  2. Vous pouvez également utiliser des transactions directement (si vous utilisez d'autres mises à jour de base de données que $model->save():

    $connection = $this->getConnection();
    $connection->beginTransaction();
    try {
        ...
        $connection->commit();
    } catch (\Exception $e) {
        $connection->rollBack();
        throw $e;
    }
Fabian Schmengler
la source
Existe-t-il un moyen pris en charge pour enregistrer plusieurs objets lors de l'utilisation de référentiels? Ils appellent en interne des save()méthodes de modèles de ressources, de sorte que chacun d'entre eux sera enregistré dans des transactions distinctes. Les référentiels contiennent souvent une logique de validation, il est donc généralement recommandé de les utiliser à la place des save()méthodes de modèle de ressource standard.
Bartosz Kubicki
1
@BartoszKubicki il y en a. Si deux modèles de ressources utilisent la même connexion (ce qu'ils font généralement, la valeur par défaut), l'enregistrement de la relation dans afterSave () de la première ressource entraînera l'ajout de requêtes à la même transaction. Regardez comment les commandes sont enregistrées, ligne par ligne. OrderRepository :: save () est le point d'entrée.
vitoriodachef