我正在编写一个Windows服务,它从MSMQ中提取消息并将它们发布到遗留系统(Baan)。如果帖子失败或机器在帖子中发生故障,我不想丢失消息。因此我使用MSMQ交易。我失败了,我承诺成功。
当针对本地队列工作时,此代码运行良好。但在生产中,我想要将运行服务的机器(或机器)与队列本身分开。当我针对远程队列进行测试时,抛出System.Messaging.MessageQueueException:“事务使用情况无效。”
我已经确认有问题的队列是事务性的。
以下是从队列中收到的代码:
// Begin a transaction.
_currentTransaction = new MessageQueueTransaction();
_currentTransaction.Begin();
Message message = queue.Receive(wait ? _queueTimeout : TimeSpan.Zero, _currentTransaction);
_logger.Info("Received a message on queue {0}: {1}.", queue.Path, message.Label);
WORK_ITEM item = (WORK_ITEM)message.Body;
return item;
我已切换到SQL Service Broker。它支持远程事务接收,而MSMQ 3.0则不支持。而且,作为一个额外的好处,它已经使用了我们集群和备份的SQL Server实例。
答案 0 :(得分:5)
我发表评论询问您正在使用的MSMQ版本,因为我认为这是导致问题的原因。事务接收未在早期版本的MSMQ中实现。如果是这种情况,那么blog post解释了您的选择。
答案 1 :(得分:3)
如果MSDTC在两台计算机上运行,则使用TransactionScope应该可以正常工作。
MessageQueue queue = new MessageQueue("myqueue");
using (TransactionScope tx = new TransactionScope()) {
Message message = queue.Receive(MessageQueueTransactionType.Automatic);
tx.Complete();
}
答案 2 :(得分:0)
我已切换到SQL Service Broker。它支持远程事务接收,而MSMQ 3.0则不支持。而且,作为一个额外的好处,它已经使用了我们集群和备份的SQL Server实例。
答案 3 :(得分:0)
为了使用事务范围,您必须在验证MSDTC被安装并激活远程客户端连接之前。
安装MSDTC不是问题,但激活远程客户端连接必须导致重启服务器(在Windows Server 2003上就是这种情况)。
也许这篇文章可以帮到你: How to activate MSDTC and remote client connection
答案 4 :(得分:0)
Aviod使用远程MSMQ(另外升级到MSMQ 4.0以支持远程MSMQ事务)。 1)或者,您可以创建一个Web服务来推送消息 2)创建本地MSMQ以进行交易 3)创建具有捆绑(批处理)编号和消息编号的小实用程序...批处理失败后删除目标处的消息,将其作为事务范围