Spring事务传播行为中可能的坑点
2024-08-26 14:22:17
一、简介
Spring事务配置及相关说明详见:https://www.cnblogs.com/eric-fang/p/11052304.html。这里说明spring事务的几点注意:
1、默认只会检查回滚RuntimeException的异常。
2、@Transactional注解只能作用于public的方法上,默认传播行为 Propagation.REQUIRED
3、service内部方法之间的调用,不会被spring拦截到,也即不会产生事务
二、坑点
主要的坑点就是在嵌套事务上,当service内部方法之间调用的时候,很可能会产生预期之外的效果。例如下例子:
saveUser保存用户,如果过程出现异常,则执行saveMsg方法。
public class UserServiceImpl implements UserService{ @Autowired
private UserDao userDao;
@Autowired
private MsgDao msgDao;
@Autowired
private MsgService msgService;
@Autowired
private UserService userService; @Transactional(propagation = Propagation.REQUIRED)
public void saveUser(User user) throws Exception {
System.out.println(user.toString());
try {
userDao.saveUser(user);
int i = 1/0;
// saveUser2(user);
} catch (Exception e) {
// msgService.saveMsg();
// this.saveMsg();
userService.saveMsg();
throw new RuntimeException();
}
} @Transactional(propagation = Propagation.REQUIRES_NEW)
public void saveMsg() {
TbMsg msg = TbMsg.builder().name("xiaocao").msg("xiaoxiao").age(27).build();
msgDao.saveMsg(msg);
}
}
单元测试,调用saveUser方法,并没有达到想要的效果(saveUser异常,SaveMsg隔离级别是REQUIRES_NEW,理论上应该能入库)。
失败原因即是上面第一节中说的:同一个service中的方法调用,不会产生新事务。Spring 事务的管理控制,主要是通过AOP的动态代理增强来实现的,目标对象本身并没有任何的事务管理能力,都是通过代理对象动态增强功能去实现事务管理。在同一个service中的方法调用,相当于是目标对象本身的this调用,并没有经过代理对象,所以自然的事务配置的嵌套均无效。
解决策略:
1、saveMsg移动到另一个service中,在UserServiceImpl中导入MsgService,saveUser中通过MsgService类去调用。
2、UserServiceImpl中注入自己,通过注入的自身service进行调用。
最新文章
- 在Angular1.X中使用CSS Modules
- java基础:所有参数皆是按值参数
- C/C++的四大内存分区 分类: C/C++ 2015-05-09 01:36 163人阅读 评论(0) 收藏
- [原] Android持续优化 - 提高流畅度
- POJ C++程序设计 编程题#4:魔兽世界之一:备战
- [shell基础]——整数比较;字符串比较;文件测试;逻辑测试符
- Resource is out of sync with the file system: 解决办法
- 从零开始学C++之继承(一):公有/私有/保护继承、overload/overwrite/override之间的区别
- Go Revel - Parameters(参数绑定)
- 以脚本方式直接执行修改密码的passwd命令
- Java多线程:wait(),notify(),notifyAll()
- Python-Django 视图层
- PyAutoGUI——让所有GUI都自动化
- NodeJS 难点(网络,文件)的 核心 stream 一:Buffer
- 浴谷八连测R6题解(收获颇丰.jpg)
- flex 设置换行flex-wrap
- LDA相关论文汇总
- 显示excel工作簿中所有工作表的名称!!!
- django中如何建立抽象型数据库作为父模块可继承其功能
- tcp/ip网络协议学习