Spring事务REQUIRED与REQUIRES_NEW:回滚事务

Maj*_*ssi 49 java spring hibernate transactions spring-transactions

我有一个具有propagation = Propagation.REQUIRES_NEW事务属性的方法:

@Transactional(propagation = Propagation.REQUIRES_NEW)
public void createUser(final UserBean userBean) {
    //Some logic here that requires modification in DB
}
Run Code Online (Sandbox Code Playgroud)

此方法可以同时调用多次,并且对于每个事务,如果发生错误而不是回滚(独立于其他事务).

问题是,这可能会迫使Spring创建多个事务,即使另一个事务可用,也可能导致一些性能问题.


Java doc propagation = Propagation.REQUIRED说:Support a current transaction, create a new one if none exists.

这似乎解决了性能问题,不是吗?

回滚问题怎么样?如果新方法调用在使用现有事务时回滚,该怎么办?即使以前的电话会不会回滚整个交易?

[编辑] 我想我的问题不够明确:

我们有数百个客户端连接到我们的服务器.

对于每个客户端,我们自然需要发送有关事务的反馈(OK或exception - > rollback).

我的问题是:如果我使用REQUIRED,是否意味着只使用了一个事务,如果第100个客户端遇到问题,第一个客户端的事务也会回滚?

Eug*_*gen 75

使用REQUIRES_NEW仅在从事务上下文调用方法时才相关; 当从非事务性上下文调用该方法时,它将表现得完全一样REQUIRED- 它将创建一个新事务.

这并不意味着所有客户端只会有一个单一事务 - 每个客户端都将从非事务性上下文开始,一旦请求处理达到a @Transactional,它就会创建一个新事务.

因此,考虑到这一点,如果使用REQUIRES_NEW对于该操作的语义有意义 - 而不是我不担心性能 - 这会使教科书过早优化 - 我宁愿强调正确性和数据完整性,并且一旦性能指标一直担心性能收集,而不是之前.

在回滚时 - 使用REQUIRES_NEW将强制启动新事务,因此异常将回滚该事务.如果还有另一个正在执行的事务 - 根据操作的具体情况,将根据异常是否在堆栈中冒泡或被捕获而将会回滚或不回滚 - 这是您的选择.此外,为了更深入地讨论交易策略和回滚,我建议:«交易策略:了解交易陷阱»,Mark Richards.


Pio*_*zda 12

如果您确实需要在单独的事务中执行此操作,则需要使用REQUIRES_NEW并承受性能开销.注意死锁.

我宁愿那样做:

  • 验证Java端的数据.
  • 在一个事务中运行每个事务.
  • 如果DB端出现任何问题 - >这是DB或验证设计的一个重大错误.回滚所有内容并抛出关键的顶级错误.
  • 写出好的单元测试.

  • 您的客户端连接到服务器将通过单独的线程,每个线程都有自己的事务。一个线程中的异常不会对其他线程的事务产生任何影响。 (3认同)