背景是:
我观察到,有时 CT 不能(但是?)能够看到 PT 的DB更改,如果已收到相应的JMS消息,则会发生事件( PT 已提交?)。
似乎JTA无法保证此类的一致性(这也在Jurgen Holler的演示“交易选择表现”中得到证实。)
避免此类问题的最佳方法是什么(除了明显的 - 不使用JTA)?
感谢。
答案 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获得脏读取更新异常。
我还没有测试过这种方法,但很可能是需要的工作,遗憾的是。