当前位置:网站首页>@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是数据库链接,只有拥有同一个数据库链接才能同时提交和回滚,在不同的数据库连接中,是不同的事务,自然无法同时提交和回滚了
边栏推荐
- Fingerprint password lock based on Hal Library
- Interval product of zhinai sauce (prefix product + inverse element)
- [postgresql]postgresql custom function returns an instance of table type
- [raid] [simple DP] mine excavation
- jvm jni 及 pvm pybind11 大批量数据传输及优化
- 11-grom-v2-05-initialization
- Rhcsa third day notes
- [effective Objective-C] - block and grand central distribution
- Print linked list from end to end
- Qtablewidget control of QT
猜你喜欢

2.7 format output of values

2022 safety officer-c certificate examination and safety officer-c certificate registration examination

In 2021, the global revenue of thick film resistors was about $1537.3 million, and it is expected to reach $2118.7 million in 2028

Camera calibration (I): robot hand eye calibration

Recommendation of books related to strong foundation program mathematics

Virtual machine installation deepin system

设计电商秒杀系统

19、 MySQL -- SQL statements and queries

Test panghu was teaching you how to use the technical code to flirt with girls online on Valentine's Day 520

AcWing 1460. Where am i?
随机推荐
强基计划 数学相关书籍 推荐
In 2021, the global revenue of thick film resistors was about $1537.3 million, and it is expected to reach $2118.7 million in 2028
Rhcsa third day operation
Micro service knowledge sorting - asynchronous communication technology
Cannot load driver class: com. mysql. cj. jdbc. Driver
【leetcode】1027. Longest arithmetic sequence (dynamic programming)
Exercises of function recursion
Phpexcel import export
Implementation of stack
MySQL 8.0 data backup and recovery
11-grom-v2-05-initialization
Microservice knowledge sorting - search technology and automatic deployment technology
[Tang Laoshi] C -- encapsulation: member variables and access modifiers
Popularize the basics of IP routing
Test changes in Devops mode -- learning and thinking
Ruby replaces gem Alibaba image
Machine learning support vector machine SVM
Global and Chinese market of cyanuric acid 2022-2028: Research Report on technology, participants, trends, market size and share
强化学习-学习笔记1 | 基础概念
Recommendation of books related to strong foundation program mathematics