2013-02-25 66 views
2

我的团队有一个windows服务,它使用http绑定托管一个wcf服务。当wcf服务收到消息时,它会立即使用NetMsmqBinding将其发送到另一个wcf服务,该服务也驻留在Windows服务中。 msmq服务处理消息并将其保存到我们的数据库中。NetMsmqBinding:邮件正在被多次处理

在开发和临时环境中,一切正常。当我们部署到生产时,我们看到发送到我们服务的消息正乘以n + 1(对于n条消息)。

例如:收到1条消息,2条保存到数据库。收到的4个消息,20保存到DB等

我们怀疑它是与交易的MSMQ服务设置,

并发,并InstanceContextMode,但我们不能弄明白。

服务的设置为:

  • InstanceContextMode:默认。
  • ConcurrenyMode:默认
  • 事务:TransactionScoreRequired = True和TransactionAutoComplete = True。
  • RetryCount重= 1,RetryCycles = 1

我们使用.NET 4中,MSMQ 3.0和Windows Server 2003

任何想法,以什么可能导致此问题?

编辑:

了大量的研究后,我们发现了以下几件事:

  • 当WCF运行时尝试提交事务的一个消息,它会抛出“交易异常异步中止“。每次消息重复时都会抛出此异常。
  • 在wcf跟踪中,我们没有看到任何异常,除了上面所述的异常。
  • 在System.Transaction跟踪中,我们看到正在打开一个事务(针对第1条消息),然后在wcf运行时创建该事务的克隆(使用属性RollbackIfNotCompleted = true)之后,几秒钟后通过跟踪中没有消息,然后同样的事情再次发生。

我们真的无能......

感谢

回答

2

好了,我们终于得到了它: 我们使用Entlib用于记录,并且我们添加了一个DB监听器。 Entlib数据库监听器使用相同的服务事务。当它试图将事务传递给数据库服务器时,会引发错误,因为数据库服务器上的MSDTC配置不正确,导致事务回滚。当WCF运行时试图提交事务时,它会因为已经中止而失败,然后它会尝试再次处理相同的消息(因为内置了重试机制)。

当我们修复MSDTC设置时,复制停止。
现在,我们需要弄清楚的是:为什么回滚到服务事务会导致消息倍增很多倍?

3

,除非您的程序中删除或TimeToBeReceived计时器到期MSMQ不会删除的消息。

如果我正确理解您的环境,您的问题可能是由于收到的消息的处理时间过长造成的。如果消息的接收和重新发送是在同一个事务中完成的,那么在第一个WCF服务最终从队列中删除之前,它可能会尝试多次读取相同的消息。

这使我下面的想法,你可以尝试:

  • 你可以尝试,收到您的原始消息后,创建具有一样的内容的新的消息,并发送新的下一WCF服务。这应该会缩短接收到的消息的生命周期。

  • 如果您需要保留的消息的顺序相同,您可以尝试Miker169的建议,更改配置为InstanceContextMode.Single , ConcurrencyMode = ConcurrencyMode.Singlehttps://stackoverflow.com/a/2610093/219344