[英]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: 我宁愿那样做:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.