作者热门文章
- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
最近,我一直在查看 RabbitMQ通过 C# 作为实现 pub/sub 的一种方式。我更习惯于使用 NServiceBus . NServiceBus 通过在 TransactionScope
中加入 MSMQ 来处理事务。其他事务感知操作也可以在相同的 TransactionScope
(如 MSSQL)中登记,因此一切都是真正的原子。在底层,NSB 引入 MSDTC 进行协调。
我看到在 RabbitMQ 的 C# 客户端 API 中有一个 IModel.TxSelect()
和 IModel.TxCommit()
。这很适合在提交之前不向交换器发送消息。这涵盖了有多个消息发送到需要原子化的交换的用例。但是,是否有一种好方法可以将数据库调用(比如 MSSQL)与 RabbitMQ 事务同步?
最佳答案
您可以通过实现 IEnlistmentNotification 编写 RabbitMQ 资源管理器以供 MSDTC 使用界面。该实现在征募参与时为事务管理器提供两阶段提交通知回调。请注意,MSDTC 的价格很高,并且会大大降低您的整体性能。
RabbitMQ 资源管理器示例:
sealed class RabbitMqResourceManager : IEnlistmentNotification
{
private readonly IModel _channel;
public RabbitMqResourceManager(IModel channel, Transaction transaction)
{
_channel = channel;
_channel.TxSelect();
transaction.EnlistVolatile(this, EnlistmentOptions.None);
}
public RabbitMqResourceManager(IModel channel)
{
_channel = channel;
_channel.TxSelect();
if (Transaction.Current != null)
Transaction.Current.EnlistVolatile(this, EnlistmentOptions.None);
}
public void Commit(Enlistment enlistment)
{
_channel.TxCommit();
enlistment.Done();
}
public void InDoubt(Enlistment enlistment)
{
Rollback(enlistment);
}
public void Prepare(PreparingEnlistment preparingEnlistment)
{
preparingEnlistment.Prepared();
}
public void Rollback(Enlistment enlistment)
{
_channel.TxRollback();
enlistment.Done();
}
}
使用资源管理器的示例
using(TransactionScope trx= new TransactionScope())
{
var basicProperties = _channel.CreateBasicProperties();
basicProperties.DeliveryMode = 2;
new RabbitMqResourceManager(_channel, trx);
_channel.BasicPublish(someExchange, someQueueName, basicProperties, someData);
trx.Complete();
}
关于c# - TxSelect 和 TransactionScope,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11739265/
最近,我一直在查看 RabbitMQ通过 C# 作为实现 pub/sub 的一种方式。我更习惯于使用 NServiceBus . NServiceBus 通过在 TransactionScope 中加
我是一名优秀的程序员,十分优秀!