【问题标题】:JMS transactionJMS 事务
【发布时间】:2012-12-03 03:21:12
【问题描述】:

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

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 将从队列中取出一条消息,如果有的话,其他消费者将无法使用该消息。

【问题讨论】:

    标签: transactions jms message-queue


    【解决方案1】:

    发送的回滚是直接的,消息不会被放入队列2。

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

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

      • 感谢您的见解。但我并不是在暗示我正在等待发送消息的回复,只是想表明状态的两个变化。我已对我的问题进行了澄清,并交换了接收/发送消息的顺序。
      猜你喜欢
      • 1970-01-01
      • 2011-06-04
      • 1970-01-01
      • 2012-08-31
      • 2017-01-30
      • 2011-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多