XA / JTA事务:在DB更改可见之前到达JMS消息

时间:2013-01-30 01:17:26

标签: java jms jta distributed-transactions xa

背景是:

  • producer(JTA事务 PT )正在向JMS队列发送消息并进行数据库更新;
  • consumer(JTA事务 CT )侦听同一队列,并在收到消息时读取DB;
  • 应用程序服务器 - WebLogic,DB - Oracle。

我观察到,有时 CT 不能(但是?)能够看到 PT 的DB更改,如果已收到相应的JMS消息,则会发生事件( PT 已提交?)。

似乎JTA无法保证此类的一致性(这也在Jurgen Holler的演示“交易选择表现”中得到证实。)

避免此类问题的最佳方法是什么(除了明显的 - 不使用JTA)?

感谢。

3 个答案:

答案 0 :(得分:4)

所以似乎没有简单,优雅和防故障的解决方案。在我们的例子中,决定依赖简单的重新传递机制(抛出异常并让JMS消息在一定时间后重新传递)。

还考虑过:

  • 将DB数据源标记为并期望上次资源提交优化(LRCO)启动(从而部分控制XA事务内部提交的顺序)。由于依赖于应用程序服务器(WL)的内部而被拒绝。

  • 将DeliveryDelay设置为JMS消息,因此只有在(假设)数据库同步结束一段时间后才能使用它。由于缺乏保证而需要在不同环境下进行微调,因此被拒绝。

其他答案中提到的

Blog post确实包含了所有这些以及其他几个选项(但没有确定的选项)。

答案 1 :(得分:1)

答案 2 :(得分:0)

关于答案:

  

“所以似乎没有简单,优雅和防故障的解决方案   那。在我们的案例中,决定依靠简单的重新发送   机制(抛出异常并让JMS消息成为   在一定时间后重新传递。“

如果您在Transaction1逻辑结束后启动的第二个事务有一种方法可以检测到事务1的更改尚未显示并且在技术异常上爆炸,那么这只是失败证明。

如果您的交易2与交易1的流程不同,则可能需要检查。交易1的输出很可能是交易2成功的必要条件。如果你有土豆,你只能制作炸薯条...如果你没有土豆,你可以炸掉,下次再试。

但是,如果因DB出现故障而导致的进程与在事务1本身上运行的进程完全相同。你只是将马铃薯加入肠道(例如数据库表)并且未能检测到你的肠道是否过度膨胀并继续运行交易以进行抽水......这样的检查可能无法完成。

有点像我的情况。

理论上的解决办法很可能是尝试通过创建一个等同于JPA的@Version字段的人工实体来引发数据库上的Dirty Read,迫使每个需要串行运行的进程来敲定更新。共同实体。如果事务2和1都更新公共实体上的公共字段,则该过程必须中断 - 要么在第二个事务上获得JPA乐观锁定异常,要么从DB获得脏读取更新异常。

我还没有测试过这种方法,但很可能是需要的工作,遗憾的是。

相关问题