立即发送JMS消息,忽略当前的TX状态

时间:2017-12-05 15:45:58

标签: jms activemq spring-transactions spring-jms

简而言之,我使用了来自spring 入门指南的超简单JMS配置:https://spring.io/guides/gs/messaging-jms/

我的情况是我想从事务方法发送JMS消息,即使TX失败了,就像(kotlin代码):

@Service
open class MyService(private val t: JmsTemplate) {
//
  @Transactional
  open fun go(sth: String) {
    val result = // some logic here
    t.convertAndSend("NeedsToBeDelivered", result)
    // more logic which might fail
  }
}

结果仅在TX成功时传递,否则 - 更多逻辑部分失败 - msg丢失。 我试图以多种不同的方式配置AMQ,也尝试了几种TX变体,但对我来说都没有。

我对此很感兴趣 1 /交付无视tx状态 2 /立即交付(直到当前TX完成后才推迟)。

建议?

更新

昨天我尝试了这个并按预期工作。

 @Transactional(propagation = NOT_SUPPORTED)
 fun sendNoTx(msg: String, destination: String) = try {
    val con = cf.createConnection() // cf stands for connection factory
    con.start()
    val session = con.createSession(false, AUTO_ACKNOWLEDGE)
    val producer = session.createProducer(session.createQueue(destination))
    producer.send(session.createTextMessage(msg))
    con.close()
 } catch (e: Exception) {
    LOG.warn("Failed to send NO TX message", e)
 }

Gary提出的更优雅的解决方案是将JmsTemplate与另一个CF实例一起提供 - 以这种方式完成它我们避免所有 conn.close()一样的混乱和异常处理。

1 个答案:

答案 0 :(得分:0)

您需要使用2个连接工厂,以便JmsTemplate不参与侦听器容器的事务。

模板会查找连接工厂上键入的事务资源(会话)。

如果它有一个不同的连接工厂,它将无法找到它并将使用自己的会话。