我遇到的问题是,在极少数情况下,来自事务性MSMQ队列的消息会被接收两次。
以下是我的设置(3台Windows 2008 R2 x64服务器):
exactlyOnce="true"
有时,重复的消息只出现在其中一个服务器上,有时两个服务器中的每个服务器都会出现重复的消息。这仅在需要处理大量消息时才会发生,并且始终在较短的时间范围内(通常<200ms)接收重复消息。
我可以检测到两次收到消息,因为每条消息都包含一个唯一的GUID,该GUID用作插入数据库的主键。当收到两次消息时,我会在日志文件中看到主键冲突错误。
我打开了WCF服务模型和消息跟踪,看到消息是两次收到两个不同的分布式事务。在这种情况下,这发生在同一台服务器上。
2012-08-16T08:31:18.4874394Z: Thread 210: Message Log Trace (message contains unique GUID 43df02cc-79c7-48ca-995f-175c22fb9e59)
2012-08-16T08:31:18.4874394Z: Thread 210: The transaction '69acc04f-4853-4680-bc13-3855f5b844d4:3782' was received for operation 'CreateWorkflow' from a transacted transport, such as MSMQ.
2012-08-16T08:31:18.6434444Z: Thread 207: Message Log Trace (message contains unique GUID 43df02cc-79c7-48ca-995f-175c22fb9e59)
2012-08-16T08:31:18.6434444Z: Thread 207: The transaction '69acc04f-4853-4680-bc13-3855f5b844d4:3789' was received for operation 'CreateWorkflow' from a transacted transport, such as MSMQ.
可能导致这种情况发生的原因,以及如何防止这种情况发生?
更新:以下是我用于发送邮件的相关代码。我如何发送消息不应该影响消息的接收方式,对吧?可能是在发送方打开TransactionScope会在发送方和接收方之间创建分布式事务吗?这真的不是这个意图。
private static readonly ChannelFactory<IWorkflowCreation> _channelFactory =
new ChannelFactory<IWorkflowCreation>(new NetMsmqBinding(NetMsmqSecurityMode.None));
private void StartWorkflow(EndpointAddress address, WorkflowData data)
{
using (var scope = new TransactionScope())
{
var client = _channelFactory.CreateChannel(address);
using ((IClientChannel)client)
{
client.CreateWorkflow(data);
}
scope.Complete();
}
}