立即发送 JMS 消息而不考虑当前的 TX 状态
Sending JMS message immediately disregarding current TX status
简而言之,我使用的超级简单的 JMS 配置取自 spring 入门指南:https://spring.io/guides/gs/messaging-jms/.
我的情况是,即使 TX 失败,我也想从事务方法发送 JMS 消息,比如(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 成功时传递,否则 - 更多逻辑部分失败 - 消息丢失。
我试图以多种不同的方式配置 AMQ,还尝试了几种 TX 变体,但 none 对我有用。
我感兴趣
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()-like 混乱和异常处理。
您需要使用 2 个连接工厂,以便 JmsTemplate
不参与侦听器容器的事务。
该模板查找以连接工厂为键的事务资源(会话)。
如果它有一个不同的连接工厂,它将找不到它,而是使用它自己的会话。
简而言之,我使用的超级简单的 JMS 配置取自 spring 入门指南:https://spring.io/guides/gs/messaging-jms/.
我的情况是,即使 TX 失败,我也想从事务方法发送 JMS 消息,比如(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 成功时传递,否则 - 更多逻辑部分失败 - 消息丢失。 我试图以多种不同的方式配置 AMQ,还尝试了几种 TX 变体,但 none 对我有用。
我感兴趣 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()-like 混乱和异常处理。
您需要使用 2 个连接工厂,以便 JmsTemplate
不参与侦听器容器的事务。
该模板查找以连接工厂为键的事务资源(会话)。
如果它有一个不同的连接工厂,它将找不到它,而是使用它自己的会话。