Spring中NESTED和REQUIRED_NEW传播行为的区别
简介
PROPAGATION_REQUIRED_NEW
:
表示当前方法必须运行在它自己的事务中。一个新的事务将被启动。如果存在当前事务,在该方法执行期间,当前事务会被挂起。如果使用JTATransactionManager的话,则需要访问TransactionManager。
PROPAGATION_NESTED
:
表示如果当前已经存在一个事务,那么该方法将会在嵌套事务中运行。嵌套的事务可以独立于当前事务进行单独地提交或回滚。如果当前事务不存在,那么其行为与PROPAGATION_REQUIRED一样。注意各厂商对这种传播行为的支持是有所差异的。可以参考资源管理器的文档来确认它们是否支持嵌套事务。
嵌套事务: 外事物异常,内事物回滚;内事物异常,外事物正常。
案例
PROPAGATION_REQUIRED_NEW案例
serviceOne层中方法
复制@Transactional(rollbackFor = Exception.class)
public void moneyTestREQUIRED_NEWOne(){
log.info("moneyTestREQUIRED_NEWOne事物名字{}", TransactionSynchronizationManager.getCurrentTransactionName());
//1.查询病人基本信息
List<TBICXX> tbicxx = basisDao.getTBICXX();
//2.根据CMZH更新TBMZFYHZ
Integer TBMZFYHZCount = tbmzfyhzDao.updateByCMZH("土登", "1903003643");
log.info("更新TBMZFYHZ影响行数{}",TBMZFYHZCount);
try {
propagationBehaviorTwo.moneyTestREQUIRED_NEWTwo();
} catch (Exception e) {
e.printStackTrace();
}
log.info("-------------事物虽然回滚了,但是逻辑继续执行------------");
}
serviceTwo层中方法
复制@Transactional(rollbackFor = Exception.class,propagation= Propagation.REQUIRES_NEW)
public void moneyTestREQUIRED_NEWTwo(){
log.info("moneyTestREQUIRED_NEWTwo事物名字{}", TransactionSynchronizationManager.getCurrentTransactionName());
//3.根据CMZH更新TBMZFYMXGH
Integer integer = tbmzfymxghDao.updateByCMZH("土登", "2107000224");
log.info("更新TBMZFYMXGH影响行数{}",integer);
int i=2/0;
}
Test层中方法
复制 /**
* 测试其传播行为
* PROPAGATION_REQUIRED_NEW:
* 表示当前方法必须运行在它自己的事务中。一个新的事务将被启动。如果存在当前事务,在该方法执行期间,当前事务会被挂起。如果使用JTATransactionManager的话,则需要访问TransactionManager
*
**/
@Test
public void testTransationalPropagationREQUIRED_NEW(){
behaviorOne.moneyTestREQUIRED_NEWOne();
}
运行前
运行后数据库数据
运行后控制台打印
结论
外事物和内事物是独立的事物,内事物异常回滚不影响外事物,外事物回滚不影响内事物。
PROPAGATION_NESTED案例
serviceOne层中方法
复制@Transactional(rollbackFor = Exception.class)
public void moneyTestNESTEDOne(){
log.info("moneyTestNESTEDOne事物名字{}", TransactionSynchronizationManager.getCurrentTransactionName());
//1.查询病人基本信息
List<TBICXX> tbicxx = basisDao.getTBICXX();
//2.根据CMZH更新TBMZFYHZ
Integer TBMZFYHZCount = tbmzfyhzDao.updateByCMZH("三筒", "1903003643");
log.info("更新TBMZFYHZ影响行数{}",TBMZFYHZCount);
try {
propagationBehaviorTwo.moneyTestNESTEDTwo();
} catch (Exception e) {
// 为了避免 org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only 该异常产生
// TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
e.printStackTrace();
}
int i=2/0; //JJ句
log.info("-------------事物虽然回滚了,但是逻辑继续执行------------");
}
serviceTwo层中方法
复制@Transactional(rollbackFor = Exception.class,propagation= Propagation.NESTED)
public void moneyTestNESTEDTwo(){
log.info("moneyTestNESTEDTwo事物名字{}", TransactionSynchronizationManager.getCurrentTransactionName());
//3.根据CMZH更新TBMZFYMXGH
Integer integer = tbmzfymxghDao.updateByCMZH("三筒", "2107000224");
log.info("更新TBMZFYMXGH影响行数{}",integer);
int i=2/0; //KK句
}
运行前数据库数据
--------------KK句注释调运行结果,JJ句开启---------------
运行后数据库数据
运行后控制台打印
--------------JJ句注释调运行结果,KK句开启---------------
运行后数据库数据
运行后控制台打印
结论
嵌套事物: 运行的是同一个事物,外事物提交,内事物回滚是通过设置回滚点来实现,具体实现过程参考:
https://www.jianshu.com/p/2f79ee33c8ad
Gitee代码地址
XFS
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~