WCF MSMQ从具有多个接收器的事务队列接收重复消息

WCF MSMQ从具有多个接收器的事务队列接收重复消息,wcf,workflow-foundation-4,msmq,msdtc,distributed-transactions,Wcf,Workflow Foundation 4,Msmq,Msdtc,Distributed Transactions,我遇到一个问题,来自事务性MSMQ队列的消息在极少数情况下会被接收两次 这是我的设置(3台Windows 2008 R2 x64服务器): 承载专用队列的MSMQ服务器。它们被配置为事务性的 托管工作流(WF4)的2台服务器通过WCF从MSMQ服务器上的远程专用队列接收消息。 每个队列有2个接收器,每个服务器1个接收器。我预计当一台服务器从队列中提取消息时,该消息将无法再次处理 以事务方式接收消息(TransactionScopeRequired=true) 接收器的netMsmqBindi

我遇到一个问题,来自事务性MSMQ队列的消息在极少数情况下会被接收两次

这是我的设置(3台Windows 2008 R2 x64服务器):

  • 承载专用队列的MSMQ服务器。它们被配置为事务性的
  • 托管工作流(WF4)的2台服务器通过WCF从MSMQ服务器上的远程专用队列接收消息。
    • 每个队列有2个接收器,每个服务器1个接收器。我预计当一台服务器从队列中提取消息时,该消息将无法再次处理
    • 以事务方式接收消息(TransactionScopeRequired=true)
    • 接收器的netMsmqBinding具有
      exactlyOnce=“true”
    • 每个收到的消息都会触发工作流实例的创建。我正在使用自定义WorkflowHostingEndpoint,因此可以根据消息的内容设置工作流ID
有时,重复消息仅出现在其中一台服务器上,有时,重复消息跨两台服务器中的每台服务器出现。只有当需要处理大量消息,并且重复消息总是在很短的时间内(通常<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();
    }
 }
private static readonly ChannelFactory\u ChannelFactory=
新的ChannelFactory(新的NetMsmqBinding(NetMsmqSecurityMode.None));
私有void StartWorkflow(端点地址、工作流数据)
{
使用(var scope=new TransactionScope())
{
var client=\u channelFactory.CreateChannel(地址);
使用((IClientChannel)客户端)
{
client.CreateWorkflow(数据);
}
scope.Complete();
}
}

请发布发送邮件的代码。请发布发送邮件的代码。