Nos damos cuenta que en la vida real, para que la información sea coherente al guardarla, necesitamos hacer que Persistence trabaje de forma transaccional. Pero la pregunta es… ¿La responsabilidad de la transacción recae en Persistence?.
Si miramos las características de las cartas, en realidad no es así. El caso de uso tiene que ser consistente, ya que podemos alterar varios Aggregates, no solo uno, con lo que la responsabilidad de gestionar la transacción en este escenario que tenemos montado recae en el Command use case, que es nuestro orquestador del flujo.
Llegados a este punto, nos damos cuenta que todos los Command use case en nuestro código deben gestionar la transaccionalidad aparte de hacer su trabajo. La solución más sencilla parecería crear una clase decoradora que gestionase esa particularidad y todos los Command use case fuesen decorados con la misma. Pero existe otra opción para descargarle dicha responsabilidad al Command use case… que con orquestar flujo tiene más que suficiente.
La carta que vamos a sacar ahora es algo incómoda de colocar, ya que vive en contacto con varias capas física y conceptualmente. Prestar atención a cómo explicarla.
Moviendo transaccionalidad a un Command bus
Sacaremos la carta de Ability Command/Query bus y la pondremos en la tercera fila, debajo de la carta de Command REST controller. La usaremos para explicar que es una habilidad que une User interface y Application layer, haciendo que podamos agregarle funcionalidad al flujo y que sirve para orquestar colaboraciones con Buses futuros que veremos más adelante.
Ahora que sabemos que con un Command bus podemos quitarle la responsabilidad de gestionar detalles de infraestructura al Command use case, debemos rellenar la cuarta fila con una carta Implementation desvelando la tecnología específica que usaremos. En nuestro caso escogemos Symfony Messenger.