Recientemente comencé a sumergirme en CQRS / ES porque podría necesitar aplicarlo en el trabajo. Parece muy prometedor en nuestro caso, ya que resolvería muchos problemas.
Esbozo mi comprensión aproximada de cómo una aplicación de ES / CQRS debe parecerse contextualizada a un caso de uso bancario simplificado (retirar dinero).
Para resumir, si la persona A retira algo de dinero:
- se emite un comando
- se entrega el comando para validación / verificación
- un evento se envía a un almacén de eventos si la validación se realiza correctamente
- un agregador pone en cola el evento para aplicar modificaciones en el agregado
Por lo que entendí, el registro de eventos es la fuente de la verdad, ya que es el registro de HECHOS, podemos derivar cualquier proyección a partir de él.
Ahora, lo que no entiendo, en este gran esquema de cosas, es lo que sucede en este caso:
- regla: un saldo no puede ser negativo
- la persona A tiene un saldo de 100e
- la persona A emite un comando WithdrawCommand de 100e
- pases de validación y se emite el evento MoneyWithdrewEvent de 100e
- mientras tanto, la persona A emite otro WithdrawCommand de 100e
- el primer MoneyWithdrewEvent no se agregó, pero la validación pasa, porque la verificación de la validación contra el agregado (que aún no se ha actualizado)
- MoneyWithdrewEvent de 100e se emite en otro momento
== > Estamos en un estado inconsistente de un saldo en -100e y el registro contiene 2 MoneyWithdrewEvent
Según tengo entendido, hay varias estrategias para hacer frente a este problema:
- a) coloque el id de la versión agregada junto con el evento en el almacén de eventos, de modo que si hay una discrepancia en la versión tras la modificación, no suceda nada
- b) utilice algunas estrategias de bloqueo, lo que implica que la capa de verificación tiene que crear de alguna manera
Preguntas relacionadas con las estrategias:
- a) En este caso, el registro de eventos ya no es la fuente de la verdad, ¿cómo lidiar con eso? Además, volvimos al cliente de acuerdo, mientras que era totalmente incorrecto permitir el retiro, ¿es mejor en este caso usar cerraduras?
- b) Locks == deadlocks, ¿tiene alguna idea sobre las mejores prácticas?
En general, ¿es correcto mi entendimiento sobre cómo manejar la concurrencia?
Nota: entiendo que la misma persona que retira dos veces el dinero en tan poco tiempo es imposible, pero tomé un ejemplo simple, para no perderse en los detalles