当开发人员代码中没有发生错误时,MSMQ WCF 事务队列消息在处理后转到毒队列

MSMQ WCF Transactional Queue Message going to Poison Queue after proccessing when no error is occurring in developer code

这实际上不是问题。而是对遇到同样问题的任何人的回答,因为我花了 2 天时间才弄清楚出了什么问题。

场景:我们有一个事务性 MSMQ 队列,我们​​通过 TransactionScopeRequired = true, TransactionAutoComplete = true

通过 WCF 接收消息

当收到一条消息时,我们的代码会正常处理它而不会出现错误,但随后消息的 'AbortCount' 会增加,并且会根据您的 MSMQ 绑定配置将其发送到重试队列或毒药队列.我们的代码中没有抛出任何错误,应该已经成功处理。

以下异常发生在任何开发人员代码之外,并且仅在禁用 'just my code' 时显示。

The transport channel detected a poison message. This occurred because the message exceeded the maximum number of delivery attempts or because the channel detected a fundamental problem with the message. The inner exception may contain additional information.

原来是在我的消息处理代码中发生了什么,我开始了一个数据库事务,然后既没有提交它(因为没有更改)也没有回滚它(错误地)。这导致环境 WCF 事务检测到中止的事务并回滚。

解决方案:如果您不提交交易,不要只处置它!所有事务都必须提交或回滚。这对某些人来说可能是显而易见的,但你不知道你不知道什么。

调用Transaction.Comit() 提交事务,而不是让它不完整地处理掉。我还注意到,如果您在内部事务中调用 .Rollback,MSMQ 环境事务不喜欢它。