Question

Je me demande simplement comment gérer au mieux les transactions entre plusieurs couches de service. Les couches de service utilisent un ORM pour stocker et récupérer à partir de la base de données. Les transactions doivent-elles être connues et traitées au sein des différentes couches de service? Ou devraient-ils être gérés par une autre couche?

Par exemple: j'ai deux couches de service pour les utilisateurs et les clients. Je voudrais:

1) Créez et enregistrez un nouveau client
2) Créer et sauvegarder un nouvel utilisateur
3) Attribuer cet utilisateur au client

Tous au sein d'une même transaction.

Un exemple simple pourrait ressembler à ceci:

$userManagementService = new UserManagementService;
$newUserData = array(...);
$newUser = $userManagementService->create($newUserData);

$clientManagementService = new ClientManagementService;
$newClientData = array(...);
$newClient = $clientManagementService->create($newClientData);

$userManagementService->assignUserToClient($newUser, $newClient);

Où la logique de transaction doit-elle aller?

Était-ce utile?

La solution

N'essayez pas de faire des transactions imbriquées dans les couches de service ou dans l'ORM.

Les transactions sont globales pour la connexion à la base de données. À moins que votre SGBDR prenne en charge les transactions imbriquées de manière native et , votre API de base de données expose des transactions imbriquées, vous pouvez rencontrer des anomalies.

Pour plus de détails, voir ma réponse à Comment détecter que cette transaction a déjà été lancée?

Puisque vous utilisez PHP, la portée de vos transactions est tout au plus une requête unique. Vous devez donc simplement utiliser des transactions gérées par conteneur, et non des transa de couche de service. En d’autres termes, démarrez la transaction au début du traitement de la demande et validez (ou annulez) à la fin du traitement de la demande.

Si une exception nécessitant une annulation se produit profondément dans les actions ORM imbriquées, classez-la en utilisant une exception et laissez le conteneur (c'est-à-dire votre contrôleur d'actions PHP) s'en charger.

Autres conseils

Faites-vous face à une agrégation de transactions? Ce pseudo-code correspond-il à ce que je pense que vous dites?

try
    begin application transaction
    begin ORM transaction 1
       create new user
       commit request
    begin ORM transaction 2
       create new client
       commit request
    begin ORM transaction 3
       create user client association
       commit request
    commit application tx
catch()
    abort ORM tx 3
    abort ORM tx 2
    abort ORM tx 1
    abort app tx

À tout moment, l'annulation d'une transaction imbriquée générera probablement une exception. Ces exceptions annuleraient logiquement toutes les transactions imbriquées du validation en deux phases .

Je ne pourrais peut-être pas obtenir ce que vous recherchez après.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top