当前位置:网站首页>@Transactional注解失效的场景
@Transactional注解失效的场景
2022-07-03 20:34:00 【cristianoxm】
Transactional用于在项目中开启事务,然后如果使用不当,也可能会导致事务失效,看看以下场景
修饰非public方法、修饰private、final、static方法
:
这3种情况都可以从spring的源码中找到原因
protected TransactionAttribute computeTransactionAttribute(Method method,
Class<?> targetClass) {
// Don't allow no-public methods as required.
if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
return null;
}
此方法会检查目标方法的修饰符是否为 public,不是 public则不会获取@Transactional 的属性配置信息
。而final、static方法无法被代理重写方法,也会导致事务失效
。
注意:private,protected、private 修饰的方法上使用 @Transactional 注解,虽然事务无效,但不会有任何报错,这是我们很容犯错的一点。
- 手动抛出别的异常, rollbackFor 设置错误
默认情况下,spring只会回滚RuntimeException和Error,对于普通的Excetion(非运行时异常),他不会回滚。因为spring团队认为非运行时异常是属于业务上的,开发人员应该主动进行处理而不是抛出给框架处理。
如果在事务中抛出其他类型的异常,但却期望 Spring 能够回滚事务,就需要指定 rollbackFor属性
。
@Transactional(rollbackFor = MyException.class)
//@Transactional//这样事务失效
public void withoutRollBackFor(User user) throws MyException {
user.setAge(423442);
userMapper.update(user,new LambdaUpdateWrapper<User>().eq(true, User::getName,user.getName()));
//普通的Excetion(非运行时异常),事务失效,除非明确指定@Transactional(rollbackFor = MyException.class)
throw new MyException();
}
- 同一个类中方法调用,导致@Transactional失效
@Service
public class UserService {
@Autowired
UserMapper userMapper;
public Integer insert(User user){
return userMapper.insert(user);
}
public void test(User user) throws MyException {
//这里其实是this.updateStatus(user);而不是proxy对象去调用
//该方式即使最后抛出了异常,到由于调用的是本对象,所以updateStatus的事务是失效的,执行完age被修改为423442
updateStatus(user);
}
@Transactional(rollbackFor = MyException.class)
public void updateStatus(User user) throws MyException {
user.setAge(423442);
userMapper.update(user,new LambdaUpdateWrapper<User>().eq(true, User::getName,user.getName()));
throw new MyException();
}
}
- 异常被 catch“吃了”导致@Transactional失效
@Transactional(rollbackFor = MyException.class)
public void rollbackFailed(User user){
try {
user.setAge(423442);
userMapper.update(user,new LambdaUpdateWrapper<User>().eq(true, User::getName,user.getName()));
throw new MyException();
}
catch (MyException e){
//手动回滚事务,不然事务失效
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//System.out.println("事务失效");
}
}
- 数据库引擎不支持事务
这种情况出现的概率并不高,事务能否生效数据库引擎是否支持事务是关键。常用的MySQL数据库默认使用支持事务的innodb引擎。一旦数据库引擎切换成不支持事务的myisam,那事务就从根本上失效了
。
- 多线程调用导致事务失效
- 背景介绍
最近有一个大数据量插入的操作入库的业务场景,需要先做一些其他修改操作,然后在执行插入操作,由于插入数据可能会很多,
用到多线程去拆分数据并行处理来提高响应时间,如果有一个线程执行失败,则全部回滚。
在spring中可以使用@Transactional注解去控制事务,使出现异常时会进行回滚,
在多线程中,这个注解则不会生效,如果主线程需要先执行一些修改数据库的操作,当子线程在进行处理出现异常时,主线程修改的数据则不会回滚,导致数据错误。
- 简单示例演示多线程事务
@Transactional(rollbackFor = MyException.class)
public void failedRollBackUnderMultipleThreads(User user) throws MyException {
user.setAge(423442);
userMapper.update(user,new LambdaUpdateWrapper<User>().eq(true, User::getName,user.getName()));
new Thread(()->{
//该事务方法是在另一个线程中,获取到的数据库链接不一样,从而跟上面是不同的是事务,即使下面抛出异常回滚,该方法也不会回滚
roleService.test();
}).start();
throw new MyException();
}
- 从源码角度分析:
spring的事务是通过数据库链接实现的,当前线程中保存了一个map,key是数据源,value是数据库链接,只有拥有同一个数据库链接才能同时提交和回滚,在不同的数据库连接中,是不同的事务,自然无法同时提交和回滚了
边栏推荐
- Virtual machine installation deepin system
- 【愚公系列】2022年7月 Go教学课程 002-Go语言环境安装
- Analysis of gas fee setting under eip1559
- 2022 low voltage electrician examination and low voltage electrician simulation examination question bank
- 你真的知道自己多大了吗?
- The 12th Blue Bridge Cup
- Basic number theory -- Chinese remainder theorem
- Qtablewidget control of QT
- Line segment tree blue book explanation + classic example acwing 1275 Maximum number
- How to do Taobao full screen rotation code? Taobao rotation tmall full screen rotation code
猜你喜欢
Explore the internal mechanism of modern browsers (I) (original translation)
Etcd 基于Raft的一致性保证
MPLS configuration
JVM JNI and PVM pybind11 mass data transmission and optimization
Viewing Chinese science and technology from the Winter Olympics (II): when snowmaking breakthrough is in progress
如临现场的视觉感染力,NBA决赛直播还能这样看?
How to read the source code [debug and observe the source code]
强化学习-学习笔记1 | 基础概念
设计电商秒杀系统
Introduction to golang garbage collection
随机推荐
MySQL master-slave synchronization principle
Shortest path problem of graph theory (acwing template)
MPLS configuration
Upgrade PIP and install Libraries
Sword finger offer 30 Stack containing min function
11-grom-v2-04-advanced query
AI enhanced safety monitoring project [with detailed code]
《ActBERT》百度&悉尼科技大学提出ActBERT,学习全局局部视频文本表示,在五个视频-文本任务中有效!...
Commands related to files and directories
Exercises of function recursion
Offset related concepts + drag modal box case
Kubernetes 通信异常网络故障 解决思路
Rhcsa third day operation
强基计划 数学相关书籍 推荐
[postgresql]postgresql custom function returns an instance of table type
Deep search DFS + wide search BFS + traversal of trees and graphs + topological sequence (template article acwing)
Producer consumer mode (multithreading, use of shared resources)
Machine learning support vector machine SVM
Thread, thread stack, method stack, the difference of creating thread
Ruby replaces gem Alibaba image