简体   繁体   English

Spring事务REQUIRED与REQUIRES_NEW:回滚事务

[英]Spring transaction REQUIRED vs REQUIRES_NEW : Rollback Transaction

I have a method that has the propagation = Propagation.REQUIRES_NEW transactional property: 我有一个具有propagation = Propagation.REQUIRES_NEW事务属性的方法:

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

This method can be called multiple times simultaneously, and for every transaction if an error occurs than it's rolled back (independently from the other transactions). 此方法可以同时调用多次,并且对于每个事务,如果发生错误而不是回滚(独立于其他事务)。

The problem is that this might force Spring to create multiple transactions, even if another one is available, and may cause some performance problems. 问题是,这可能会迫使Spring创建多个事务,即使另一个事务可用,也可能导致一些性能问题。


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

This seems to solve the performance problem, doesn't it? 这似乎解决了性能问题,不是吗?

What about the rollback issue ? 回滚问题怎么样? What if a new method call rolls back while using an existing transaction ? 如果新方法调用在使用现有事务时回滚,该怎么办? won't that rollback the whole transaction even the previous calls ? 即使以前的电话会不会回滚整个交易?

[EDIT] I guess my question wasn't clear enough: [编辑]我想我的问题不够明确:

We have hundreds of clients connected to our server. 我们有数百个客户端连接到我们的服务器。

For each client we naturally need to send a feedback about the transaction (OK or exception -> rollback). 对于每个客户端,我们自然需要发送有关事务的反馈(OK或exception - > rollback)。

My question is: if I use REQUIRED , does it mean only one transaction is used, and if the 100th client encounters a problem the 1st client's transaction will rollback as well ? 我的问题是:如果我使用REQUIRED ,它是否意味着只使用了一个事务,如果第100个客户端遇到问题,第一个客户端的事务也将回滚?

Using REQUIRES_NEW is only relevant when the method is invoked from a transactional context; 使用REQUIRES_NEW仅在从事务上下文调用方法时才有意义; when the method is invoked from a non-transactional context, it will behave exactly as REQUIRED - it will create a new transaction. 当从非事务性上下文调用该方法时,它的行为与REQUIRED完全相同 - 它将创建一个新事务。

That does not mean that there will only be one single transaction for all your clients - each client will start from a non-transactional context, and as soon as the the request processing will hit a @Transactional , it will create a new transaction. 这并不意味着所有客户端只会有一个单一事务 - 每个客户端都将从非事务性上下文开始,一旦请求处理将命中@Transactional ,它将创建一个新事务。

So, with that in mind, if using REQUIRES_NEW makes sense for the semantics of that operation - than I wouldn't worry about performance - this would textbook premature optimization - I would rather stress correctness and data integrity and worry about performance once performance metrics have been collected, and not before. 因此,考虑到这一点,如果使用REQUIRES_NEW对该操作的语义有意义 - 我不会担心性能 - 这会使教科书过早优化 - 我宁愿强调正确性和数据完整性,并且一旦性能指标有性能就会担心性能已被收集,而不是之前。

On rollback - using REQUIRES_NEW will force the start of a new transaction, and so an exception will rollback that transaction. 在回滚时 - 使用REQUIRES_NEW将强制启动新事务,因此异常将回滚该事务。 If there is also another transaction that was executing as well - that will or will not be rolled back depending on if the exception bubbles up the stack or is caught - your choice, based on the specifics of the operations. 如果还有另一个正在执行的事务 - 根据操作的具体情况,将根据异常是否在堆栈中冒泡或被捕获而将会回滚或不回滚 - 这是您的选择。 Also, for a more in-depth discussion on transactional strategies and rollback, I would recommend: «Transaction strategies: Understanding transaction pitfalls», Mark Richards . 此外,为了更深入地讨论交易策略和回滚,我建议: «交易策略:了解交易陷阱»,Mark Richards

If you really need to do it in separate transaction you need to use REQUIRES_NEW and live with the performance overhead. 如果您确实需要在单独的事务中执行此操作,则需要使用REQUIRES_NEW并使用性能开销。 Watch out for dead locks. 注意死锁。

I'd rather do it the other way: 我宁愿那样做:

  • Validate data on Java side. 验证Java端的数据。
  • Run everyting in one transaction. 在一个事务中运行每个事务。
  • If anything goes wrong on DB side -> it's a major error of DB or validation design. 如果DB端出现任何问题 - >这是DB或验证设计的一个重大错误。 Rollback everything and throw critical top level error. 回滚所有内容并抛出关键的顶级错误。
  • Write good unit tests. 写出好的单元测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 REQUIRES_NEW在Spring + Hibernate中不创建新交易 - REQUIRES_NEW not creating a new transaction in spring+hibernate Spring真的用REQUIRES_NEW开始新的交易吗? - Does Spring actually start a new transaction with REQUIRES_NEW? Spring 事务从 NOT_SUPPORTED 到 REQUIRES_NEW 的传播 - Spring Transaction Propagation from NOT_SUPPORTED to REQUIRES_NEW 在 Spring Boot 的 for 循环中使用 REQUIRES_NEW 的事务问题 - Transaction problem using REQUIRES_NEW in a for loop with Spring Boot 内部事务(REQUIRES_NEW)抛出异常时外部事务回滚 - External transaction rollback when internal transaction(REQUIRES_NEW) throw exception Spring交易REQUIRES_NEW是否会传播到方法中的方法? - Will Spring transaction REQUIRES_NEW be propagated to the methods within the method? 为什么不提交 Requires_New 的事务? - Why does not commit transaction of Requires_New? Sprint事务-如果内部事务失败,则REQUIRES_NEW行为 - Sprint transaction - REQUIRES_NEW behavior if the inner transaction fails Spring可以/应该将Hibernate会话重用于子事务(REQUIRES_NEW) - Can/should Spring reuse Hibernate Session for sub-transaction (REQUIRES_NEW) REQUIRES_NEW:Spring 外部事务回滚,而不是在内部回滚时持久化 - REQUIRES_NEW: Spring outer transaction rollbacks also instead of persisting when inner rollbacks
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM