RabbitMQ Integration with Database Transactions

Imagine a situation:

var txn = new DatabaseTransaction(); var entry = txn.Database.Load<Entry>(id); entry.Token = "123"; txn.Database.Update(entry); PublishRabbitMqMessage(new EntryUpdatedMessage { ID = entry.ID }); // A bit more of processing txn.Commit(); 

Now, the EntryUpdatedMessage consumer can receive this message before transaction txn is committed and, therefore, cannot see the update.

Now I know that RabbitMQ does support transactions on its own, but we cannot use them because we create a new IModel for each publication and having a model for each thread is really cumbersome in our script (ASP.NET application website).

I was thinking about having a list of messages that should be published during the database transaction, but this is really a smelly solution.

What is the correct way to solve this problem?

+14
source share
1 answer

RabbitMQ recommends that you use publisher confirmations rather than transactions. Transactions do not work well.

In any case, transactions usually do not work very well with a service-oriented architecture. It is better to adopt a "ultimately sequential" approach where the failure can be repeated later and duplicate idempotent messages are ignored.

In your example, I would update the database and commit it before posting the message. When the publisher confirms the return, I would update the field in the database record to indicate that the message was sent. Then you can start the sweeping process, check for unsent messages and send them in your path. If the message has passed, but for any reason the confirmation or subsequent record of the database failed, you will receive a duplicate message. But that doesn’t matter because you designed your posts as idempotent.

+28
source

All Articles