I read this nice post from Jonathan Oliver on how to handle events out of turn.
http://blog.jonathanoliver.com/cqrs-out-of-sequence-messages-and-read-models/
The solution we use is to remove the message from the message and place it in the "storage table" until all messages with the previous sequence are received. When all previous messages have been received, we accept all messages from the waiting table and run them sequentially through the appropriate handlers. After all the handlers are completed successfully, we delete messages from the holding table and commit updates for the read models.This works for us because the domain publishes the events and marks them with the corresponding sequence number. Without this, the solution below would be much more difficult, if not impossible.This solution uses the relational database as a storage mechanism persistence, but did not use any of the relational aspects of the engine storage location. At the same time, all this is a warning. If messages 2, 3 and 4 appear, but message 1 is never executed, we do not apply any of them. The script should happen only in case of an error to process message 1 or message 1 is somehow lost. Fortunately, its easy enough to fix errors in our message handlers and re-run messages. Or, in the event of a lost message, rebuild the read models from the event store directly.
The solution we use is to remove the message from the message and place it in the "storage table" until all messages with the previous sequence are received. When all previous messages have been received, we accept all messages from the waiting table and run them sequentially through the appropriate handlers. After all the handlers are completed successfully, we delete messages from the holding table and commit updates for the read models.
This works for us because the domain publishes the events and marks them with the corresponding sequence number. Without this, the solution below would be much more difficult, if not impossible.
This solution uses the relational database as a storage mechanism persistence, but did not use any of the relational aspects of the engine storage location. At the same time, all this is a warning. If messages 2, 3 and 4 appear, but message 1 is never executed, we do not apply any of them. The script should happen only in case of an error to process message 1 or message 1 is somehow lost. Fortunately, its easy enough to fix errors in our message handlers and re-run messages. Or, in the event of a lost message, rebuild the read models from the event store directly.
, , , , .
, , , . currentEventNumber!= lastReceivedEventNumber + 1
, . " ", . , , . , .
, , . , sp_getapplock MSSQL " " . Apache ZooKeeper , , .
, , - (ES). . , ( ), ( ). ES. . ES- UnitOfWork. ( QM). db.
, (S1), , (S2).
, , (O1) , . , (S1) , (S1) (S2) (O1), (S1). .
Source: https://habr.com/ru/post/1661339/More articles:Interface Iteration - typesSplit control, dimming the contents with the panel open - uwptyping redux repository using flowtype method and typed stream - javascriptElasticsearch connection error in Ubuntu 16.4 - linuxMac OSX: Android Studio quits unexpectedly on first launch - androidLaravel 5.3 How to show username in email - laravelКак установить LLVM/Clang/libС++ версию 3.9 на Travis-CI? - libc++Find the ultimate overall variability of max and minimum matrix - matrixКак я могу анимировать видимость элемента управления в UWP с использованием визуальных состояний? - animationWhy is this code compiled with a free monad interpreter? - scalaAll Articles