validation - ¿Cómo manejar la validación de coherencia basada en el conjunto en CQRS?
domain-driven-design eventual-consistency (4)
Debido a que la verificación de exclusividad se realizaría antes de la escritura de datos, entonces el mejor método es crear un servicio de seguimiento de eventos, que enviará una notificación cuando el proceso finalice o finalice.
Tengo un modelo de dominio bastante simple que implica una lista de raíces agregadas de Facility
. Dado que estoy usando CQRS y un bus de eventos para manejar los eventos surgidos del dominio, ¿cómo podría manejar la validación en los conjuntos? Por ejemplo, supongamos que tengo el siguiente requisito:
-
Facility
deben tener un nombre único.
Dado que estoy utilizando una base de datos eventualmente coherente en el lado de la consulta, no se garantiza que los datos que contiene sean precisos en el momento en que el evento procesa o procesa el evento.
Por ejemplo, un FacilityCreatedEvent
está en la cola de procesamiento de eventos de la base de datos de consultas esperando a ser procesado y escrito en la base de datos. Se CreateFacilityCommand
un nuevo CreateFacilityCommand
al dominio para ser procesado. Los servicios de dominio consultan la base de datos de lectura para ver si hay otras Facility
registradas con ese nombre, pero devuelven falso porque CreateNewFacilityEvent
aún no se ha procesado y escrito en la tienda. El nuevo CreateFacilityCommand
ahora tendrá éxito y arrojará otro FacilityCreatedEvent
que explotaría cuando el procesador de eventos intente escribirlo en la base de datos y descubra que ya existe otro Facility
con ese nombre.
En este caso, puede implementar un servicio de estilo CRUD simple que básicamente hace una inserción en una tabla Sql con una restricción de clave primaria.
La inserción solo ocurrirá una vez. Cuando los comandos duplicados con el mismo valor que deberían existir solo una vez llegan al agregado, el agregado llama al servicio, el servicio falla la operación de inserción debido a una violación de la restricción de clave principal, arroja un error, todo el proceso falla y no hay eventos se generan, no hay informes en el lado de la consulta, tal vez un informe de la falla en una tabla para la comprobación de coherencia eventual donde el usuario puede consultar para conocer el estado del procesamiento del comando. Para comprobarlo, simplemente consulte una y otra vez el Modelo de Vista del Estado del Comando con la Guía del Comando.
Obviamente, cuando el comando tiene un valor que no existe en la tabla para la comprobación de la clave principal, la operación es un éxito.
La tabla de la restricción de clave primaria solo debe usarse como un servicio, pero, debido a que implementó el abastecimiento de eventos, puede reproducir los eventos para reconstruir la tabla de restricciones de claves primarias.
La solución que elegí fue agregar una raíz agregada del System
que pudiera mantener una lista de los nombres actuales de la Facility
. Al crear una nueva Facility
, utilizo el agregado del System
(solo un System
como un objeto global / singleton) como una fábrica para él. Si el nombre de la instalación dada ya existe, arrojará un error de validación.
Esto mantiene las restricciones de validación dentro del dominio y no se basa en el almacén de consultas finalmente consistente.
Tres enfoques se describen en Eventual Consistency and Set Validation :
- Si el problema es poco frecuente o no es importante, trátelo administrativamente, posiblemente enviando una notificación a un administrador.
- Envíe un evento DuplicateFacilityNameDetected, que podría iniciar un proceso de resolución automatizado.
- Mantenga un servicio que conozca los nombres de las instalaciones utilizadas, tal vez escuchando los eventos de dominio y manteniendo una lista persistente de nombres. Antes de crear cualquier instalación nueva, consulte primero con este servicio.
Consulte también esta pregunta relacionada: validación de exclusividad cuando se utiliza CQRS y aprovisionamiento de eventos