java在Spring事务中的行为差异需要新的和嵌套的传播
前言
首先:
它不是Differences between requires_new and nested propagation in Spring transactions的副本-我读了它,但我没有找到我问题的答案
问题:
在阅读了我提到的主题后,我了解到在物理事务计数方面传播级别之间的主要区别:
2 db事务-用于REQUIRES_NEW
外部和内部方法
1 db事务-用于外部方法和内部方法的NESTED
。如果基础数据库不支持保存点,它将不起作用
但从我的观点来看,逻辑似乎是一样的
如何理解在实践中使用哪个级别?有了解它的用例吗?行为差异的简便例子
p.S.
我认为,由于事务提交时间不同,其他事务的差异也存在一些可见性
p.S.2
此外,我认为存在性能差异:
@Transactional
public void outer(){
for(int i=0;i<100500;i++){
inner();
}
}
@Transactional
public void inner(){
//some logic
}
在这种情况下,嵌套将更好,因为1个长物理事务而不是100500+1
# 1 楼答案
我看到的最大区别是:
在嵌套的情况下:
如果需要新的:
对于性能,如果其他因素不重要,您可以在事务大小和事务编号之间找到平衡点。i、 m.O如果嵌套的速度比要求的快,那么这个问题没有一般的答案
# 2 楼答案
在您的示例中,如果
inner()
有:然后,如果它在
outer()
循环中抛出第二个调用的异常,那么来自第一个调用的更改将已经由它的REQUIRES_NEW
提交如果
inner()
有:然后,来自第一个调用的更改将回滚—因为
outer()
中没有catch块inner()
上的传播级别真正开始起作用的地方是outer()
循环是否要处理inner()
中的异常:显然
REQUIRES_NEW
和NESTED
只会保留来自成功的inner()
调用的更改。不过,关键的区别在于NESTED
,如果outer()
中出现后续故障,仍然可以选择将其全部丢弃正如您所说的,另一个因素是可伸缩性——一些数据库可能不了解具有
NESTED
传播的父事务的大小此外,这可能值得一提——尽管我怀疑这只是为了在示例中清晰起见。直接调用
this.inner()
会绕过Spring事务顾问。需要允许它注入一个“建议bean”,以允许@Transactional
注释在调用前后发挥其魔力-例如nextAutowiredBean.inner()