没有交易的毒消息

Poison messages without transactions

如果消息是非事务性的,它会中毒吗?

文档似乎没有暗示,但我没有找到任何直接声明。

是的,在某些情况下是可能的。

毒消息是一种位于队列顶部的消息,阻止其他消息通过。现在,是什么让事务性消息中毒了?这是当我们回滚事务并且消息返回到之前的位置时,就在队列的顶部。所以这与消息本身无关(至少不是直接的),而是我们处理消息的方式以及处理失败时我们所做的事情的结果,即执行回滚。

如果队列是非事务性的,并且我们 "Receive" 从队列顶部发送消息,它是不可逆的。没有回滚会将消息放回该顶部位置。如果我们想将该消息放回队列以便稍后重试,我们所能做的就是发送原始消息的副本。 MSMQ Send 将它放在队列的末尾。所以它不能阻止其他消息。

有一种情况不适用,那就是如果我们使用消息优先级并以高于队列其余部分的优先级将其发回。那会把它放回顶部并创建有毒消息场景。

另一种方法是,如果我们的处理包括 "Peek"(不删除消息),如果处理正常,则后跟 "Receive"。如果在 Peek 和 Receive 之间处理失败,消息将保留在队列顶部。

所以,是的,非事务性消息可能包含有毒消息,但前提是以特定方式执行操作。