简而言之,我使用了来自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()一样的混乱和异常处理。
答案 0 :(得分:0)
您需要使用2个连接工厂,以便JmsTemplate
不参与侦听器容器的事务。
模板会查找连接工厂上键入的事务资源(会话)。
如果它有一个不同的连接工厂,它将无法找到它并将使用自己的会话。