2012-02-26 10 views
18

Estoy tratando de implementar mi propia infraestructura CQRS con Event Sourcing para conocerla mejor. Como proyecto de ejemplo, estoy implementando un motor de blog, sé que podría no ser el ajuste perfecto, pero solo quiero trabajar en algo real.Validación de unicidad cuando se utiliza CQRS y aprovisionamiento de eventos

El problema al que he llegado ahora es la validación. Cada publicación tiene un shortUrl, y el shortUrl debe ser único, pero ¿dónde debo poner esta validación en el dominio? Sé que tendré esa validación antes incluso de enviar el comando leyendo mi tienda de lectura para verificar si es válida al crear un comando de crear publicación o actualizar el comando de publicación.

Puedo pensar en dos "soluciones".

  1. Tener un agregado Blog que guarda el registro de todos los ajustes relacionados con el blog y también referencias a todos los postes. Pero el problema con esto en mi opinión es que tengo que manejar la comunicación entre los agregados en ese escenario, así como cada vez que necesito validar la singularidad de un shortUrl Necesito leer todos los eventos de la tienda de eventos para crear todas las publicaciones y eso parece complicado.
  2. La segunda alternativa que tengo es cuando se desencadena el evento y mi controlador de eventos que crea el modelo de lectura desencadena un evento de URL corto duplicado cuando se da cuenta de que tendrá dos direcciones URL cortas que apuntan a diferentes publicaciones. ¿Es válido tener el modelo de lectura para disparar eventos cuando detecta errores?

¿Hay más alternativas? Tenga en cuenta que sé que mi dominio podría no ser el más adecuado para cqrs y DDD, pero estoy haciendo esto para aprender en un dominio pequeño.

+0

Ver: http://stackoverflow.com/questions/2916899/how-to-handle-set-based-consistency-validation-in-cqrs –

Respuesta

0

Depende de lo que "el negocio" quiera que suceda. Si desea que el cliente (creador de los comandos) sea responsable de elegir una URL corta, debe tener una tienda de lectura que verifique la singularidad de la misma. Cuando el usuario escribe una URL corta, la vista debe verificar que la URL corta sea única y presente un error de validación si no lo es. Cada vez que se guarda una publicación, un evento publicará la información actualizada (incluida la URL corta) que mantiene la tienda de lectura sincronizada.

+1

Eso es lo que quiero decir con "Sé que tendré esa validación incluso antes de enviar el comando, leí en mi tienda de lectura para verificar si es válido al crear un comando de crear publicación o actualizar el comando de publicación ". Pero no es garantía de que todavía sea único cuando se trata del dominio. Esto es muy poco probable que ocurra al crear publicaciones de blog, pero creo que es un escenario interesante que todavía necesito resolver cómo resolver al usar CQRS. Lo que quiero decir es ¿cómo manejo el cheque en el dominio? –

+0

En el sistema en el que estoy trabajando, hay una restricción única en el almacén de datos, de modo que si se produce el caso límite de dos salvaciones simultáneas de diferentes entidades con un campo en conflicto, la restricción provoca una excepción hasta la UI donde puede ser arreglado manualmente A menos que la lógica del dominio pueda rectificar ese escenario, debe ser tratado por un humano. – RyanR

1

Me gustaría un servicio de dominio que sea responsable de generar ShortURL únicos. Puede usar un DB transaccional para implementar este comportamiento. Normalmente, este servicio sería utilizado por el comando que maneja parte del agregado de BlogPost. Si hay un ShortURL duplicado, puede disparar un DuplicateUrlErrorEvent. Puede preconfigurar esto en la interfaz de usuario (pero nunca en un 100%) creando un modelo de consulta delgado que use el mismo origen de datos, para que pueda consultar si una URL corta es única antes de enviar la publicación (según lo describe @ RyanR responder).

0

He leído las diferentes respuestas sobre esta y la pregunta relacionada.

La decisión se reduce a la corrección. Si puede ser indulgente y aceptar un comportamiento imperfecto por algún grado de operación, su problema es mucho más simple de resolver, especialmente bajo garantías de consistencia débil.

Sin embargo, si desea coherencia, debe utilizar un servicio de persistencia que tenga sólidas garantías de consistencia.

Por ejemplo, el comando que crea la URL corta validará que la tienda de lectura ya no contiene una URL corta y solo confirmaremos nuestro evento, si podemos confirmar los cambios en nuestra tienda de lectura primero.

Si podemos comprometer nuestros cambios a nuestra tienda de lectura, no hemos violado ninguna restricción de exclusividad (suponiendo que su tienda de lectura imponga tal restricción) y entonces podemos continuar.

Sin embargo, dado que tenemos dos transacciones no necesariamente en la misma base de datos, podríamos fallar después de la primera confirmación. Esto está bien porque la operación también fallará en su conjunto. La tienda de lectura reflejará un estado incoherente durante un tiempo, pero en el momento en que reparen, el agregado del almacén de lectura volverá a estar en un estado constante.

Como un procedimiento de mantenimiento, podríamos reparar periódicamente agregados que han estado sujetos a posibles errores. Y puede hacerlo introduciendo un indicador de error que solo se borra si ambas transacciones se realizan correctamente.

Hubo un ejemplo en el que un banco permitiría a un usuario sobregirar su cuenta porque tienen recargos para compensar. Esto plantea preguntas porque parece descuidado resolver un problema como ese, incluso perezoso. Algunos lo llaman inteligente. No se que pensar. El banco probablemente tenga suficiente dinero para cubrirlo, por lo que es mejor que lo ignoren, pero el mundo no funciona así. De todos modos, estoy divagando.

Desde una posición correcta, nuestra tienda de lectura tiene una sólida garantía de consistencia y escribimos nuestra proyección de tal forma que no podemos comprometer una transacción con la tienda de lectura si la balanza se pone en negativo. Como tal, lo peor que puede pasar es que se deduzca un cargo de la tienda de lectura, pero la operación nunca se ha comprometido por completo en la tienda del evento. El usuario vería que faltaba dinero en su cuenta hasta que el procedimiento de mantenimiento notara el indicador de error y sanó la cuenta. Esto creo que es un compromiso de trabajo.

Cuestiones relacionadas