@Transactional注解失效的情况
该篇博客主要介绍@Transactional注解失效的12种情况,我是看b站的一个up主进行搬运总结的,希望对我、对你都有一点一点的帮助。
1、访问权限的问题
private、default、protected、public,他们的权限从左到右,依次变大。
把某些事务方法,定义成错误的访问权限,就会导致事务功能出问题。即不是public类型就会失效
2、方法用final修饰
事务是通过AOP完成,即通过代理的方式完成,将一个方法定义成final意味着该方法不能被重写了,那么事务就失效了。
注意:如果某个方法是static时,同样无法通过动态代理,变成事务方法。
3、方法内部调用
在某个Service类的某个方法中,调用另外一个是事务方法,比如:
-
-
public class UserService{
-
-
private UserService userService;
-
-
//@Transactional
-
public void add(UserModel userModel){
-
userMapper.insertUser(userModel);
-
updateStatus(userModel);
-
}
-
-
-
public void updateStatus(UserModel userModel){
-
doSameThing();
-
}
-
}
以上方法中采用的是this对updateStatus()方法进行调用的,因此updateStatus不能生成事务。
解决以上问题可以将自身进行注入的方式
-
-
public class ServiceA{
-
-
private ServiceA serviceA;
-
-
public void save(User user){
-
queryData1();
-
queryData2();
-
serviceA.daSave(user);
-
}
-
-
public void daSave(User user){
-
addData1();
-
uodateData2();
-
}
-
}
4、未被spring管理
在开发过程中容易忽略一些细节问题,比如忘记了@Controller、@Service、@Component、@Repository等注解
没使用以上注解交给spring进行管理,那么事务就不会生效。
5、多线程调用
在实际项目开发中,多线程的使用场景还是挺多的。如果spring事务用在多线程场景中,会有什么问题
我们说的同一事物,其实是指同一个数据库连接,只有拥有同一个数据库连接才能同时提交和回滚。如果在不同的线程,拿到的数据库连接肯定是不一样的,所以是不同的事务。
6、表不支持事务
mysql5之前,默认的数据库引擎是MYISAM,它的好处是:索引文件和数据文件是分开存储的,对于查多写少的单表操作,性能比innodb更好。
7、未开启事务
如果你使用的是springboot项目,那么springboot通过DataSourceTransactionaManagerAutoConfiguration类,已经默默地帮你开启了事务,你只需要配置spring.datasource相关参数即可。
如果使用的还是传统的spring项目,那么你需要在applicationContext.xml文件中,手动配置事务相关参数。如果忘了配置,事务肯定是不会生效的。
二、事务不回滚
8、错误的传播特性
其实,在使用@Transactional注解时,是可以指定propagation参数的。
该参数得作用是指定事务的传播特性,spring目前支持7中传播特性:
REQUIRED
SUPPORTS
MANDATORY
REQUIRES_NEW
NOT_SUPPORTED
NEVER
NESTED
如果事务设置成Propagation.NEVER,这种类型的传播特性不支持事务,如果有事务则抛出异常。
9、自己吞了异常
事物不会回滚,最常见的问题是:开发者在代码中手动try...catch了异常。比如:
-
-
-
public class UserService{
-
-
public void add(UserModel userModel){
-
try{
-
saveData(userModel);
-
updateData(userModel);
-
}catch(Exception e){
-
log.error(e.getMessage,e);
-
}
-
}
-
}
这种情况下spring事务当然不会回滚,因为开发者自己捕获了异常,又没有手动抛出,换句话说就是把异常吞掉了。
如果想要spring事务能够正常回滚,必须抛出它能够处理的异常,如果没有抛出异常,则spring认为程序是正常的。
10、手动抛出了别的异常
即使开发者没有手动捕获异常,但是抛出的异常不正确,spring事务也不会回滚。
-
-
-
public class UserService{
-
-
public void add(UserModel userModel) throws Exception{
-
try{
-
saveData(userModel);
-
updateData(userModel);
-
}catch(Exception e){
-
log.error(e.getMessage,e);
-
throw new Exception(e);
-
}
-
}
-
}
上面的情况,开发人员自己捕获了异常:Exception,事务同样不会回滚。
因为spring事务,默认情况下只会回滚RuntimeException(运行时异常)和Error(错误),对于普通的Exception(非运行时异常),它不会回滚。
11、自定了回滚异常
在使用@Transactional注解声明事务时,有时我们想自定义回滚异常,spring也是支持的。可以通过设置rollbackFor参数,来完成这个功能。
-
-
-
public class UserService{
-
-
public void add(UserModel userModel) throws Exception{
-
saveData(userModel);
-
updateData(userModel);
-
}
-
}
如果在执行上面这段代码,保存和更新数据时,程序报错了,抛出了SqlException、DuplicateKeyException等异常。而BusinessException是我们自定义的异常,报错的异常不属于BusinessException,所以事务也不会回滚。
12、嵌套事务回滚多了
-
public class UserService{
-
-
private UserMapper userMapper;
-
-
-
private RoleService reloService;
-
-
-
public void add(UserModel userModel) throws Exception{
-
userMapper.insertUser(userModel);
-
roleService.doOtherThing();
-
}
-
}
-
-
-
public class RoleService{
-
-
public void doOtherThing(){
-
System.out.println("保存role表数据");
-
}
-
}
这种情况使用了嵌套的内部事务,原本是希望roleService.doOtherThing方法时,如果出现了异常,只回滚doOtherThing方法里的内容,不回滚userMapper.insertUser里的内容,即回滚保存点,但事实是,insertUser也回滚了。
可以使用下面的方式进行事务的回滚。
-
public class UserService{
-
-
private UserMapper userMapper;
-
-
-
private RoleService reloService;
-
-
-
public void add(UserModel userModel) throws Exception{
-
userMapper.insertUser(userModel);
-
try{
-
roleService.doOtherThing();
-
}catch(Exception e){
-
log.error(e.getMessage(),e);
-
}
-
}
-
}
-
-
-
public class RoleService{
-
-
public void doOtherThing(){
-
System.out.println("保存role表数据");
-
}
-
}
学习之所以会想睡觉,是因为那是梦开始的地方。
ଘ(੭ˊᵕˋ)੭ (开心) ଘ(੭ˊᵕˋ)੭ (开心)ଘ(੭ˊᵕˋ)੭ (开心)ଘ(੭ˊᵕˋ)੭ (开心)ଘ(੭ˊᵕˋ)੭ (开心)
------不写代码不会凸的小刘
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhfhhffg
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01