只有在确定要提交但在提交之前才拦截事务

Intercept transaction only when is sure to be committed but before is committed

上下文是 Java - 带有 Hibernate 和 Spring 的 JPA。

让我们以两阶段提交协议的场景为例(但只有一个资源):

  1. 要从应用程序提交的查询

  2. 投票Yes/No(在我们的案例中来自数据库)

3.1。如果是,来自数据库

3.1.1。 (在代码中进行回调)- 不是协议的一部分

3.1.2。提交到数据库

3.2 如果没有

3.2.1 回滚到数据库

我想要的是一种在代码中从 3.1.1 回调的方法,但只有在知道事务将被提交时,但在实际提交之前。另外,如果这里抛出异常,那么应该回滚事务。

使用 Spring 中的 TransactionSynchronization (*),允许您在 committed/completed 之前或 committed/completed 之后拦截交易。

现在看来,我想要的似乎是另一个完整的两阶段提交协议;但我想知道 Spring 中是否有解决方法。不同的是在回调中完成的调用不能回滚。

来自 Spring 4.2 的

(*) 使用 @TransactionalEventListenerTransactionPhase 非常简单,它很好地抽象了 TransactionSynchronization

我只想先回到事务,作为一个要么全部通过要么全部失败的工作单元。根据你所说的方法,它不能回滚,需要在事务的开始和结束之间执行,那么很抱歉,你没有事务。

你可以在你的方法中做很多检查以确保回滚的可能性非常小,但你的方法总是有机会执行并发生回滚,但这种机会可能非常小可以忽略不计,你可能对此感到满意,我不知道。

编辑: 我觉得打个比方就好了。

案例一: 所以典型的交易例子是在商店买香蕉,如果你没有钱,或者商店没有香蕉,商店没有钱,你也没有香蕉,这就是通常发生的事情。但是,如果设置了所有条件,则事务将成功提交。

案例 2: 现在回答您的问题。为了争论起见,假设你是一个小偷,如果你能侥幸逃脱,你只想偷香蕉。这个你不能确定,因为你问的是未来,除非你是算命的,否则你去偷香蕉的时候可能会被抓到。

如果你回到第一种情况,你可以检查你有钱,商店有香蕉,给商店你的钱,把所有的顾客赶出去,锁上商店的门,所以商店是处于不可改变的状态。去做你不能回滚的方法,回到商店,拿走香蕉。没有人能保证香蕉还会在那里,但很有可能。

您的情况是您的资源之一与两阶段提交不兼容(不是 XA-capable)。您的想法朝着 XA 段和 http://www.javaworld.com/article/2077963/open-source-tools/distributed-transactions-in-spring--with-and-without-xa.html

的最后资源策略 中描述的模式方向发展

last resource gambit的使用在

的答案中有简要说明

顺便说一下,您的问题没有提到您使用的是哪种事务管理器实现(JBossTS、Bitronix JTA、Atomikos Transaction Essentials,...)。