需要春季事务与REQUIRES_NEW:回滚事务

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

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

此方法可以同时调用多次,如果发生错误,则对于每个事务,此方法将回滚(独立于其他事务)。

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


Java文档 说:propagation = Propagation.REQUIREDSupport a current transaction, create a new one if none exists.

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

回滚问题如何?如果新方法调用在使用现有事务时回滚,该怎么办?这不会回滚整个事务,甚至以前的调用吗?

[编辑]我想我的问题不够清楚:

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

对于每个客户端,我们自然需要发送有关事务的反馈(OK 或异常 ->回滚)。

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


答案 1

仅当从事务上下文调用方法时,使用才相关;当从非事务性上下文中调用该方法时,它的行为将完全符合 - 它将创建一个新事务。REQUIRES_NEWREQUIRED

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

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

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


答案 2

如果你真的需要在单独的事务中做到这一点,你需要使用并承受性能开销。注意死锁。REQUIRES_NEW

我宁愿以另一种方式做:

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

推荐