在使用Spring的事务注解@Transactional的时候遇到几个坑
来源:互联网 发布:通用工具箱软件 编辑:程序博客网 时间:2024/05/17 03:26
今天在用@Transactional的时候遇到几个很奇怪的问题,一段从旧程序上拷过来的代码结果死活不执行,让我百思不得其解。
旧的代码是这样的,一直运行正常
@Override public Pager getPager(Map<String, Object> paramMap) { List<TaSjjhLog> logList = TaSjjhLog.getWaitingList(); if(logList != null && logList.size() > 0){ this.saveList(logList); } return this.dao.getPager(paramMap); } @Transactional private void saveList(List<TaSjjhLog> logList) { for (TaSjjhLog log : logList) { log.setErrorMessage(this.handleErrorMsg(log.getErrorMessage())); this.dao.save(log); } TaSjjhLog.removeAllFromWaitingList(logList); }新的代码是这样的,结果保存操作不起作用
@Override public List<ChangeLog> getList(Pager<ChangeLog> pager, String mc) { List<changelog> logList = ChangeLog.getWaitingList(); if(logList != null && logList.size() > 0){ this.service.saveList(logList); } return this.dao.getList(pager, mc); } @Transactional private void saveList(List<ChangeLog> logList) { logList.stream().forEach(log->{ log.setErrorMessage(this.handleErrorMsg(log.getErrorMessage(), log.getRecordCount(), log.getExecutedCount())); this.dao.save(log); ChangeLog.removeFromWaitingList(log); }); }</changelog>
起初我还以为是Lambda表达式的问题,改写了一下,结果是一样的。
然后我就不停的测试,不停的改@transactional的事务级别,结果都没用。
然后我就看我的dao里面的基类,结果发现了一点不同
旧代码在dao的基类上加了@Transactional,而新代码则是加了@Transactional(readOnly=true)
所以dao里面的save方法,旧代码是有事务的,而新代码则是只读的事务。可以问题来了,为什么我在新代码的saveList上加的事务注解不起作用?
我在网上没有找到相应的解释,但是通过我的测试和对spring的认识,我觉得spring的事务是通过切面(或者也可以说是代理)实现的,当你调用一个代理类的接口,如果其标注了事务注解,则会生效,
而我这个saveList是在service里面自己的方法调用的,这个注解不会被处理。
于是我修改代码,结果使用了三种方案全部失败:
1. 在getList上加事务注解,取消saveList上的注解:这种方式可以保存数据成功,但是查询出来的数据在SpringMVC转换结果为json的时候报错,说no session.
2. 在dao基类的save方法上加注解:结果同上
3. service提供两个接口给controller,分别是getList和saveList,都加上事务注解:结果还是同上。
经验告诉我,当你的请求包含了提交事务的时候,你同时又读了数据,并且需要在controller或是view层懒加载数据,则会有问题,因为事务一提交就关闭了。
我唯一不能理解的是我先调用saveList,提交了事务,保存了数据,我再调用getList,按理应该重新生成事务,可是为什么到controller这里还是没有session了。
最后没办法,我把读写两个事情在controller层也分开为两个接口,在jsp里面做两次请求来处理。
总结一下:
1. service里面的方法如果不是对外的接口,加事务注解没有用
2. 一个请求里面如果包含了提交事务(非只读),同时又查询数据的话,查询的数据要立即加载,不能到view层再调用session去懒加载数据。
- 在使用Spring的事务注解@Transactional的时候遇到几个坑
- spring的事务注解@Transactional
- 在使用spring mvc时,我使用了@Service这样的注解, 发现使用注解@Transactional声明的事务不起作用
- 在使用spring mvc时,我使用了@Service这样的注解, 发现使用注解@Transactional声明的事务不起作用
- 基于@Transactional注解的Spring事务
- Spring事务注解@Transactional的坑爹陷阱
- SpringBoot学习-事务注解@Transactional的使用
- 事务457——spring事务注解Transactional的propagation传播属性使用
- 事务457——spring事务注解Transactional的propagation传播属性使用
- Spring 的 @Transactional事务
- @Transactional注解在spring中的应用-事务
- spring 事务注解@Transactional
- spring 事务注解@Transactional
- spring 事务注解@Transactional
- Spring注解事务@Transactional
- Spring 注解@Transactional 事务
- 使用Spring中的 @Transactional注解控制事务
- spring丶基于@Transactional注解的事务配置,声明式事务管理的使用
- 关于卡尔曼滤波视频目标跟踪的一个疑惑
- 二叉树的最大深度 & 二叉树的最小深度
- VS2013UP4用EF6连接MySql解决方案
- Problem M
- TabLayout+ViewPage+Fragment的使用
- 在使用Spring的事务注解@Transactional的时候遇到几个坑
- Android 5.0 动画-Ripple和RevealEffect
- pointwise linux ubuntu 安装 纪录
- JDBC
- hdu2037 今年暑假不AC
- 多线程安全CAS实现的无锁
- Unity3D开发基础组件提取总结
- openssl 线程安全 Windows
- 四 、Hive逻辑优化