![](/img/trans.png)
[英]What happens to message if a JMS transaction is neither Committed nor Rolled back
[英]JMS message not rolled back after connection lost during 2PC prepare
我正在尝试解决以下问题:
TL;DR 在准备 2PC 期间,当与队列管理器的连接丢失时,如何确保发生回滚。
==================================================== ========
但是,消息不会回滚。 我没有看到任何事务日志(我相信这是可以预料的,因为准备工作没有完成)。 队列或回退队列上没有未提交的消息。
如果我在接收到消息之后但在事务提交之前在AbstractPollingMessageListenerContainer.receiveAndExecute中放置一个断点,我可以看到该消息不再在队列中。 所以看起来 session.commit 是否已经发生。 在准备 2PC 期间,当与队列管理器的连接丢失时,如何确保发生回滚。 我可能在这里遗漏了一些东西,但我看不出是什么。
经过更多的挖掘,我相信我找到了问题所在。 现在,当我在准备 2PC 期间断开与队列管理器的连接时,消息会回滚。 希望这可能对其他人有所帮助。
在我的问题中,我提到在AbstractPollingMessageListenerContainer.receiveAndExecute中放置一个断点。 在我使用 5.2.20.RELEASE 的春季版本中,代码如下所示:
if (this.transactionManager != null) {
// Execute receive within transaction.
TransactionStatus status = this.transactionManager.getTransaction(this.transactionDefinition);
boolean messageReceived;
try {
messageReceived = doReceiveAndExecute(invoker, session, consumer, status);
}
catch (JMSException | RuntimeException | Error ex) {
rollbackOnException(this.transactionManager, status, ex);
throw ex;
}
this.transactionManager.commit(status);
return messageReceived;
}
这看起来有点奇怪,因为transactionManager.commit没有被 try catch 包围。 那么如果提交失败会发生什么?
try-catch 是在 5.3.16 中添加的,见https://github.com/spring-projects/spring-framework/pull/1807
if (this.transactionManager != null) {
// Execute receive within transaction.
TransactionStatus status = this.transactionManager.getTransaction(this.transactionDefinition);
boolean messageReceived;
try {
messageReceived = doReceiveAndExecute(invoker, session, consumer, status);
}
catch (JMSException | RuntimeException | Error ex) {
rollbackOnException(this.transactionManager, status, ex);
throw ex;
}
try {
this.transactionManager.commit(status);
}
catch (TransactionException ex) {
// Propagate transaction system exceptions as infrastructure problems.
throw ex;
}
catch (RuntimeException ex) {
// Typically a late persistence exception from a listener-used resource
// -> handle it as listener exception, not as an infrastructure problem.
// E.g. a database locking failure should not lead to listener shutdown.
handleListenerException(ex);
}
return messageReceived;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.