event-handling domain-driven-design optimistic-locking eventual-consistency domain-events

event handling - Eventos de dominio y versiones sin CQRS



event-handling domain-driven-design (4)

Hola, tengo el siguiente senario que no entiendo cómo obtener la coherencia final con:

  1. El usuario 1 usa la interfaz de usuario basada en tareas para cambiar el nombre del cliente
  2. App Service llama a la operación en el agregado
  3. Evento de incendios globales en el nombre de cliente cambiado
  4. el bus envía un mensaje usando nservicebus
  5. El servicio NServicebus muere
  6. El usuario 2 obtiene agregado y las llamadas cambian de dirección
  7. Operación agregada llamada
  8. Evento de dominio disparado
  9. Mensaje puesto en bus
  10. El autobús se reinicia
  11. El mensaje 2 recogió primero
  12. Mensaje 2 procesado y otro contexto delimitado actualizado con nueva dirección
  13. Mensaje 1 recogido ahora que es orden incorrecto
  14. Que pasa ahora

En 13, ¿habría un error de concurrencia optimista si pasamos la versión del agregado en el evento?

Si es así, se aplica el mensaje 1 nuevo al objeto en el otro contexto. ¿Cómo mantenemos la consistencia?

Este es el problema que me impide aplicar eventos en mi dominio. Toda ayuda de bienvenida.

La idea esencial es actualizar otro agregado en otro contexto. Simplemente estoy atrapado en los tecnicismos de concurrencia de esto.

No estamos utilizando el abastecimiento de eventos o CQRS en el sentido de controlador de comando y comandos push en el bus. Es solo el procesamiento de eventos que queremos que ocurra de manera asíncrona ya que tenemos un diseño existente que no deseamos cambiar.

Blair


De acuerdo con esto , debes preguntarte:

¿Cuál es el impacto comercial de tener una falla?

En su caso actual, tiene este problema una vez en un millón de solicitudes. No creo que tenga un gran impacto en el negocio si acepta las dos solicitudes como válidas.


En general, estarías haciendo cola con los mensajes. Si van a una cola, obtendrás un orden adecuado. Si desea utilizar algo que no es compatible con el pedido de su bus de servicio, agregue un número de secuencia a sus eventos para que el otro lado pueda reordenarlos adecuadamente. TCP ha estado haciendo esto desde 1981 http://www.ietf.org/rfc/rfc793.txt :)


Un tema similar con NServiceBus se trata aquí . El OP propone el uso de IBus.HandleCurrentMessageLater () para girar hasta que llegue el otro mensaje. Esto puede funcionar, pero puede ser problemático ya que nunca sabes cuánto tiempo tienes que esperar.

Una opción más complicada sería usar una saga que esperaría hasta que hayan llegado todos los mensajes previos a una versión en particular. En este caso, la secuenciación se realiza en función de la versión y solo es posible si todos los cambios en la versión global se publican en el otro BC. Supongamos que el mensaje 1 opera en la versión 2 del agregado. Luego incrementa la versión del agregado y publica un evento que indica que ha operado en la versión 2. El mensaje 2 opera en la versión 3 del agregado y publica un evento que indica que ha operado en la versión 3. Cuando el punto final NServiceBus en el otro BC recibe el mensaje 2 antes del mensaje 1, sabe que el último mensaje recibido operaba en la versión 1 del agregado, por lo que necesita uno que haya operado en la versión 2. Se iniciará una saga que está esperando el siguiente mensaje. Una vez que recibe el Mensaje 1, la saga aplicará el Mensaje 1 y luego el Mensaje 2 y liberará el estado de la saga. Si el uso de la versión para secuenciación no es aceptable, se puede utilizar otra estrategia de secuenciación.


Oops : Me di cuenta de que en realidad usaste 2 tareas diferentes en tu ejemplo (nombre del cliente y luego dirección del cliente). Por supuesto, esto no sería un problema ya que la orden realmente no debería importar. Pero dejaré mi respuesta en caso de que tu intención fuera tener dos del mismo tipo de cambio.

Como siempre, me vienen a la mente un par de preguntas / cuestiones:

En primer lugar, su ejemplo no requiere que falle un punto final ya que 2 usuarios podrían actualizar la dirección al mismo tiempo y el orden del procesamiento puede ser aleatorio. Entonces la pregunta es cuál es la dirección correcta. Para resolver eso se requiere un análisis un poco más. Por un lado, supongo que podríamos suponer que un cliente no se movería con tanta frecuencia que 2 usuarios están actualizando la dirección al mismo tiempo (o incluso cerca de ella) --- :)

Aun así, tal vez la primera dirección es la correcta.

Creo que para un escenario así quieres identificar si la concurrencia, o incluso alguna otra tolerancia, es un problema. Entonces, tal vez una dirección solo se puede cambiar una vez al día y cualquier otro cambio requiere alguna otra interacción. Entonces, un manejo de excepciones sería una opción.

Realmente no debería llevar esto a un nivel técnico para tratar de resolverlo, sino más bien observar las implicaciones del proceso / negocio.

Para una solución simple, iría con la fecha de envío del mensaje correspondiente a la fecha de la última operación para un tipo específico. Entonces, para ChangeAddressCommand cuando procesa un mensaje, puede compararlo con el actual LastAddressChange y si el mensaje fue enviado antes de la última fecha de cambio, entonces, bórrelo.