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.
Esbocé mi comprensión aproximada de cómo debería verse una aplicación ES / CQRS contextualizada a un caso de uso bancario simplificado (retirar dinero).
Para resumir, si la persona A retira algo de dinero:
- se emite un comando
- el comando se entrega 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 retira 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, entonces podemos derivar cualquier proyección 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 una orden de retiro de 100e
- la validación pasa y se emite el evento MoneyWithdrewEvent of 100e
- Mientras tanto, la persona A emite otra orden de retirada de 100e
- el primer MoneyWithdrewEvent no se agregó todavía, por lo tanto, la validación pasa, porque la verificación de validación con el agregado (que aún no se ha actualizado)
- MoneyWithdrewEvent de 100e se emite otra vez
==> Estamos en un estado inconsistente de un saldo de -100e y el registro contiene 2 MoneyWithdrewEvent
Según tengo entendido, hay varias estrategias para hacer frente a este problema:
- a) coloque la identificación de versión agregada junto con el evento en el almacén de eventos, por lo que si hay una versión que no coincide con la modificación, no sucede nada
- b) utilice algunas estrategias de bloqueo, lo que implica que la capa de verificación tiene que crear una 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 él? Además, regresamos al cliente bien, mientras que era totalmente incorrecto permitir el retiro, ¿es mejor en este caso usar bloqueos?
- b) Bloqueos == puntos muertos, ¿tiene alguna idea sobre las mejores prácticas?
En general, ¿entiendo bien 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 perderme en detalles