![](/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.