php database design-patterns transactions domain-driven-design

php - MĂșltiples capas de servicio y transacciones de base de datos



database design-patterns (2)

Me pregunto cómo manejar mejor las transacciones en varias capas de servicio. Las capas de servicio usan un ORM para almacenar y recuperar desde la base de datos. ¿Deben conocerse y manejarse las transacciones dentro de las capas de servicio individuales? ¿O deberían ser manejados por otra capa?

Por ejemplo: tengo dos capas de servicio para usuarios y clientes. Me gustaría:

1) Crear y guardar un nuevo cliente
2) Crear y guardar un nuevo usuario
3) Asignar ese usuario al cliente

Todo dentro de una sola transacción.

Un ejemplo simple podría verse así:

$userManagementService = new UserManagementService; $newUserData = array(...); $newUser = $userManagementService->create($newUserData); $clientManagementService = new ClientManagementService; $newClientData = array(...); $newClient = $clientManagementService->create($newClientData); $userManagementService->assignUserToClient($newUser, $newClient);

¿A dónde debe ir la lógica de las transacciones?


¿Estás frente a una agregación de transacciones? ¿Este pseudo código coincide con lo que creo que estás diciendo?

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

En cualquier punto, una reversión de una transacción anidada arrojará una excepción, y esas excepciones lógicamente revertirán todas las transacciones anidadas en la confirmación en dos fases .

Puede que no obtenga lo que buscas, aunque.


No intente hacer transacciones anidadas dentro de las capas de servicio o dentro del ORM.

Las transacciones son globales a la conexión DB. A menos que su RDBMS admita transacciones anidadas de forma nativa y su API DB expone transacciones anidadas, puede encontrar anomalías.

Para obtener más información, consulte mi respuesta a ¿Cómo detectar esa transacción que ya se inició?

Como usa PHP, el alcance de sus transacciones es como máximo una sola solicitud. Por lo tanto, solo debe usar transacciones administradas por contenedor, no transacciones de capa de servicio. Es decir, comience la transacción al inicio de la gestión de la solicitud y comprométala (o retrotúyala) cuando termine de gestionar la solicitud.

Si se produce una excepción que requiere una reversión en lo profundo de las acciones ORM anidadas, entonces aumente la burbuja utilizando una excepción y deje que el contenedor (es decir, su controlador de acción PHP) se encargue de ello.