Context是Java - 带有Hibernate和Spring的JPA。
让我们采用两阶段提交协议的方案(但只有一个资源):
从应用程序提交的查询
投票是/否(在我们的案例中来自数据库)
3.1。如果是,则来自数据库
3.1.1。 (在代码中进行回调) - 不是协议的一部分
3.1.2。提交数据库
3.2如果没有
3.2.1回滚到数据库
我想要的是一种在代码中从3.1.1进行回调的方法,但只有当知道事务将被提交但在实际提交之前。此外,如果此处抛出异常,则应回滚该事务。
使用Spring中的TransactionSynchronization
(*),允许您在事务提交/完成之前或提交/完成之后拦截事务。
beforeCommit()
回调表示在调用方法后仍可能发生回滚; beforeComplete()
afterCommit/Complete()
并且无法回滚。 现在我看起来似乎我想要的是另一个完整的两阶段提交协议;但我想知道Spring中是否有解决方法。区别在于回调中完成的调用无法回滚。
来自Spring 4.2的(*)非常简单,@TransactionalEventListener
和TransactionPhase
很好地抽象TransactionSynchronization
答案 0 :(得分:1)
我只想首先回到交易中,作为一个工作单元,要么全部通过,要么全部失败。关于你的方法,你无法回滚,并且需要在交易的开始和结束之间执行,那么我很遗憾地说你没有交易。< / p>
你可以在你的方法中做很多检查,以确保回滚的可能性非常小,但是你的方法总是有可能执行并且发生回滚,但是这个机会可能是极其微不足道的,你可能对此感到高兴,我不知道。
修改强> 我认为类比会很好。
案例1: 所以交易的典型例子是在商店买香蕉,如果你没有钱,或商店没有香蕉,商店没有钱,你不会买香蕉,这就是什么通常会发生。但是如果设置了所有条件,那么事务将成功提交。
案例2:现在问你的问题。为了论证,可以说你是一个小偷,如果你能逃脱它,你只想偷香蕉。你无法确切地知道这一点,因为你对未来的询问,除非你是一个算命先生,当你去偷香蕉时,你可能会被抓住。
如果你回到第一个案例,你可以检查你有钱,商店有香蕉,给商店你的钱,把所有的顾客扔出去,锁门到商店,所以商店在不可改变的状态。去你的方法,你可以回滚,回到商店,并采取香蕉。没有人可以向你保证香蕉仍然存在,但很有可能。
答案 1 :(得分:1)
您的情况是您的某个资源与两阶段提交不兼容(不是支持XA的)。您的想法是针对{{3>}
段 XA和最后资源开发 中描述的模式的方向 的答案中简要解释了最后资源开局的使用顺便说一句,您的问题并未提及您使用的事务管理器的哪个实现(JBossTS,Bitronix JTA,Atomikos Transaction Essentials,...)。