【问题标题】:Intercept transaction only when is sure to be committed but before is committed仅在确定提交但在提交之前才拦截事务
【发布时间】:2017-01-08 06:36:20
【问题描述】:

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

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

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

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

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 的 @TransactionalEventListenerTransactionPhase 非常简单,它们很好地抽象了 TransactionSynchronization

【问题讨论】:

  • 您是否在尝试模仿两阶段提交?你试过<tx:jta-transaction-manager/> 吗?它在春季提供两阶段提交。
  • @Zeus 是的,但不完全;在回调方法中完成的调用不应该也不能回滚。将看看 JtaTransactionManager。不用说回调只是代码回调,不是完全实现 XA 的资源。
  • 您是否考虑过使用 Spring PlatformTransactionManager?查看 Spring 文档,这是一个您可以实现和传递的接口。
  • @JohnHarris 我希望在不需要实施的情况下获得现有的支持;但连接到现有框架总比没有好。

标签: java spring jpa transactions spring-transactions


【解决方案1】:

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

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

last resource gambit的使用在How to set up Spring Boot + Bitronix + non-XA Datasource + XA JMS Connection的回答中简单说明

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

【讨论】:

  • 没有 XA 事务管理器,因为它不是必需的,因为只有数据库支持它。
【解决方案2】:

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

您可以在您的方法中进行大量检查,以确保回滚的可能性非常小,但您的方法总是有可能执行并发生回滚,但这种可能性可能非常微不足道,并且我不知道你可能对此感到满意。

编辑: 我认为类比会很好。

案例 1: 所以经典的交易例子是在商店买香蕉,如果你没有钱,或者商店没有香蕉,商店没有钱,你没有香蕉,这是正常情况。但是如果设置了所有条件,那么事务将成功提交。

案例 2: 现在回答您的问题。为了争论,假设你是一个小偷,如果你能逃脱惩罚,你只想偷香蕉。你无法确定这一点,因为你问的是未来,除非你是算命先生,否则当你去偷香蕉时,你可能会被抓住。

如果你回到第一个案例,你可以检查你有钱,商店有香蕉,给商店你的钱,把所有的顾客都赶出去,锁上商店的门,这样商店就在不变的状态。去做你无法回滚的方法,回到商店,拿香蕉。没有人能保证香蕉还会在那里,但很有可能。

【讨论】:

  • 我不希望使用该方法的事务无法回滚。如果数据库事务成功,我只想拦截数据库事务并调用该方法;并且数据库知道/可以这样做,因为它完全支持 XA 事务。这是技术问题,不是理论问题;或命名问题。
  • 我认为你对否决票有点苛刻。你会看到我所说的在这里得到了回应:stackoverflow.com/questions/128377/….
猜你喜欢
  • 2019-06-04
  • 1970-01-01
  • 2015-01-09
  • 1970-01-01
  • 2015-01-10
  • 2011-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多