6

数据库事务是一个熟悉的概念。

try {
  ...
  ..
  updateDB()
  ..
  ...
  commit();
} catch error {
  rollback();
}

如果发生任何错误,updateDB 所做的任何更改都将被丢弃。

我想知道消息队列事务回滚将撤消什么。

try{
  ...
  ...
  //EDIT: swapped the order of receive and send
  Message m = queue1.receiveMessage(..)
  ..
  ..
  queue2.sendMessage(..)
  ..
  ..
  commit();
} catch error {
  rollback();
}

具体来说,回滚会做什么

  1. 取消发送消息
  2. 取消接收消息,即将收到的消息放回队列

还是我将数据库 tx 类比延伸得太远了。

谢谢

编辑:我并不是暗示发送和接收操作是相关的。我只想说有两个操作可以改变消息代理的状态——receive 将从队列中取出一条消息,如果有的话,其他消费者将无法使用该消息。

4

2 回答 2

10

发送的回滚是直截了当的,消息不会被放入 queue2。

接收回滚通常会将消息放回队列 (queue1)。根据您的 JMS 提供程序设置和配置,消息将被重新传递多次。如果事务回滚太多次(太多是可配置的),它将被放入“回退队列”(或死信队列),这样它就不会阻塞队列中的其他消息。回退的消息通常需要一些手动错误处理。

于 2012-12-15T09:59:42.560 回答
0

是的,你把它拉得太远了。

在交易模式下,您queue.receiveMessage()将永远不会返回(假设它被设置为等待特定的回复消息,而不仅仅是“任何”消息),仅仅是因为queue.sendMessage()还没有真正发送消息(它将在交易完成时发送)坚定的)。

顺便说一句,这是一个常见的错误。当使用 JMS(它是一种异步协议)进行同步通信时,很自然地将发送/接收周期视为由一个事务组成。然而,事实并非如此。一旦你sendMessage()在交易模式下发行,什么都不会发生;只有在提交事务时才会发送消息。

于 2012-12-15T07:27:23.360 回答