Transactional integrity.
Legion112 opened this issue · comments
If I have a database operation in the message handler and in that handler I dispatch new messages, is there a guaranty those messages will be dispatch after the database transaction is completed?
In the NServiceBus they first save all messages in the database and only after try to send messages to a message system (for example, RabbitMQ). Those give guaranty message will be dispatch only if massing handler succeeds successfully (No error occur).
Does this implementation do the same thing?
Good evening. No, in the default implementation there is no save before sending.
Instead, there are many attempts to write to the queue.
If there are many attempts to write to the queue, does it do message de duplications?
If the attempt confirmation was lost on the way back, trying to write it again will cause the message to be repeated.
Do I need to handle it myself?
The message will not be duplicated. Either it will be written to the queue or an error will be returned.
In theory, it is possible that we will not be able to process the response frame (i mean amqp frame), but this is extremely unlikely. In this case, the error handling mechanism will automatically try to execute the handler again and the message will be duplicated. But for this, all the planets must line up
The network might be interrupted when the queue sends back that it successfully saved the message but the ServiceBus didn't get the response due to a network problem.
Or what if in the handler I am willing to dispatch events A and B. The process successfully dispatches event A but after that (power-lost, the process has been killed by OS) message B has not been dispatched.
In case if we save the message first to the database and only after the business transaction has been completed try to send it to the queue. It would solve those kinds of problems.
This is undoubtedly a possible solution.
Many enterprise frameworks do this, but everything comes at a price.
I am currently working with Axon, who is doing the same and I cannot say that this is justified. In 99.9...9% of cases this leads only to a significant degradation of speed and nothing else.
Here you need to decide for yourself what is more important. ServiceBus still adheres to the strategy of an acceptable victim.
In the first versions, there was support for Unit of Work, with commit and confirmation, but as a result it was removed as unnecessary. The current implementation will not allow this.