与数据库事务集成

与数据库事务集成

本文介绍了将 RabbitMQ 与数据库事务集成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

想象一下情况:

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();

现在 EntryUpdatedMessage 的使用者可能会在提交事务 txn 之前 获得此消息,因此将无法看到更新.

Now a consumer of EntryUpdatedMessage can potentially get this message before the transaction txn is committed and therefore will not be able to see the update.

现在,我知道 RabbitMQ 本身确实支持事务,但我们不能真正使用它们,因为我们为每个发布创建了一个新的 IModel 并且在我们的场景中拥有每线程模型真的很麻烦(ASP.NET Web 应用程序).

Now, I know that RabbitMQ does support transactions by itself, but we cannot really use them because we create a new IModel for each publish and having a per-thread model is really cumbersome in our scenario (ASP.NET web application).

我想过在提交数据库事务时发布要发布的消息列表,但这是一个非常糟糕的解决方案.

I thought of having a list of messages due to be published when a DB transaction is committed, but that's a really smelly solution.

处理这个问题的正确方法是什么?

What is the correct way of handling this?

推荐答案

RabbitMQ 鼓励您使用发布者确认而不是事务.交易表现不佳.

RabbitMQ encourages you to use publisher confirms rather than transactions. Transactions do not perform well.

无论如何,事务通常不适用于面向服务的架构.最好采用最终一致"的方法,这样可以在以后重试失败并忽略重复的幂等消息.

In any case, transactions don't usually work very well with a service oriented architecture. It's better to adopt an 'eventually consistent' approach, where failure can be retried at a later date and duplicate idempotent messages are ignored.

在您的示例中,我会在发布消息之前进行数据库更新并提交.当发布者确认返回时,我将更新数据库记录中的一个字段以指示消息已发送.然后,您可以稍后进行清扫程序,检查未发送的消息并在途中发送.如果消息确实通过,但由于某种原因确认或后续数据库写入失败,您将收到重复消息.但这并不重要,因为您已将消息设计为幂等的.

In your example I would do the database update and commit it before publishing the message. When the publisher confirm returns, I would update a field in the database record to indicate that the message had been sent. You can then have a sweeper process come along later, check for unsent messages and send them on their way. If the message did get through, but for some reason the confirm, or subsequent database write failed, you will get a duplicate message. But that won't matter, because you've designed your messages to be idempotent.

这篇关于将 RabbitMQ 与数据库事务集成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-04 04:34