聊一聊使用Spring事物时不生效的场景
前言
今天介绍一下Spring事物不生效的场景,事物是我们在项目中经常使用的,如果是Java的话,基本上都使用Spring的事物,不过Spring的事物如果使用不当,那么就会导致事物失效或者不回滚,最终导致数据不一致,所以很有必要去研究一下Spring事物不生效的一些场景,避免掉坑。
下面我们意义列举不生效的场景,并给出解决方法。
一.类没被Spring管理
如果我们的类没有被Spring管理,那么即使使用了Spring事物也不会生效,要让Spring管理我们的类,需要标注@Component,@Service等注解。

二.没有标注@Transactional注解的方法调用了标注@Transactional注解的方法
如果一个方法没有使用@Transactional注解,但是它去调用了带@Transactional注解的方法,那么当前方法的事物不生效。
public void saveUser(User user) throws Exception {
save(user);
}
@Transactional(rollbackFor = Exception.class)
public void save(User user) {
try {
userDao.save(user);
exceptionMethod();
roleService.save(user.getRole());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
如上所示,saveUser方法调用了save方法,但是saveUser没有标@Transactional注解,而它调用了save方法,save方法标了@Transactional,不过事物不会生效,这是因为方法没被代理,直接是普通方法调用,所以事物自然不生效。
如果一个方法中调用了其他方法,需要在主方法上加@Transactional注解这个方法才能被代理,如下代码,当然,远程调用@Transactional就不生效了,就需要分布式事物了。
@Transactional(rollbackFor = Exception.class)
public void saveAnnotation(User user) throws Exception {
save(user);
}
public void save(User user) {
try {
userDao.save(user);
exceptionMethod();
roleService.save(user.getRole());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
三.异常使用不正确
如果异常使用不当,那么事物也不会生效,这里的异常有两种,一种是我们抛出的异常,一种是@Transactional注解所接受的异常。
1.如果我们在程序代码中自己捕获了异常导致Spring事物捕获不到异常,那么事物也不会生效,如下,exceptionMethod方法捕获了异常并打印异常信息,那么异常并不会被Spring事物捕获到,所以事物并不会回滚。
@Transactional(rollbackFor = Exception.class)
public void saveAnnotation(User user) throws Exception {
userDao.save(user);
exceptionMethod();
roleService.save(user.getRole());
}
private void exceptionMethod() throws Exception {
try {
int i = 1 / 0;
} catch (Exception e) {
e.printStackTrace();
}
}
如果需要事物回滚,那么就需要将异常抛到saveAnnotation方法,这样Spring事物才能感知到异常,从而进行事物回滚。
2.@Transactional注解有一个属性rollbackFor,它代表回滚的异常,也就是说只有捕获到这种异常事物才会回滚,它默认的是RunTimeException。
@Transactional
public void saveAnnotation(User user) throws Exception {
userDao.save(user);
exceptionMethod();
roleService.save(user.getRole());
}
private void exceptionMethod() throws Exception {
try {
int i = 1 / 0;
} catch (Exception e) {
throw new Exception("抛出异常");
}
}
如上代码,exceptionMethod方法抛出了Exception异常,而@Transactional注解我们没有指定rollbackFor,所以使用的是默认的RunTimeException,所以事物不能回滚,如果我们需要事物回滚,需要让rollbackFor指定的异常是抛出异常的父类或者和自己一样才行,如下所示。
@Transactional(rollbackFor = Exception.class)
public void saveAnnotation(User user) {
userDao.save(user);
exceptionMethod();
roleService.save(user.getRole());
}
private void exceptionMethod() {
try {
int i = 1 / 0;
} catch (Exception e) {
throw new ArithmeticException("运算异常");
}
}
四.不正确的传播行为
如果传播行为使用的是NOT_SUPPORTED,那么事物无法回滚。NOT_SUPPORTED表示当前方法不应该有事务,如果有事务存在,将它挂起,以无事务状态运行。
@Transactional(propagation = Propagation.NOT_SUPPORTED)
五.方法修饰为private
如果方法以private修饰,那么方法将不会被代理,事物自然不会生效,不过如果在进行业务开发的时候,对于需要其它类进行调用的方法,我们都是以public修饰,因为如果以private修饰,其它类想要访问的话需要借助反射才能访问,在IDEA中,@Transactional方法如果修饰为private,会有错误提醒,但是运行不会报错。

不过一些场景我们可能需要反射调用,所以不应该避开这个问题,还是将其修饰为public。
六.数据库不支持事物
如果数据库不支持事物,那么即使项目中使用了Spring事物,也不会生效,因为Spring的事物最终也是JDBC的事物,JDBC事物也要数据库支持事物才行,MySQL中MyISAM存储引擎不支持事物,InnoDB才支持事物。
七.没有配置事务管理器,导致事务失效。
使用非SpringBoot项目,需要配置PlatformTransactionManager,需要加上@EnableTransactionManagement注解,如果是SpringBoot项目,那么可以不用配置,因为SpringBoot默认帮我们装配好了,我们直接使用就好。
聊一聊使用Spring事物时不生效的场景的更多相关文章
- 集成Spring事物管理
什么是事物 事物是访问数据库的一个操作序列,数据库应用系统通过事物集来完成对数据库的存取.事物的正确执行使得数据库从一种状态转换为另一种状态. 事物必须服从ISO/IEC所制定的ACID原则.ACID ...
- MyBatis6:MyBatis集成Spring事物管理(下篇)
前言 前一篇文章<MyBatis5:MyBatis集成Spring事物管理(上篇)>复习了MyBatis的基本使用以及使用Spring管理MyBatis的事物的做法,本文的目的是在这个的基 ...
- spring事物的传播行为
1.spring事物的传播行为,主要是用来解决业务层拥有事物的方法,相互调用的问题. 2.声明事物, 在代码执行前,开启事务.代码执行完,提交事务 3.spring并没有提供事务具体的处理,而只是调用 ...
- spring事物深入了解
1.问题 1.以前对事物的了解只是停留在声明式事物,配置xml,或使用注解,事物的传播行为也只用过REQUIRED和SUPPORTS,可以说对事物的了解很模糊. 2.直到在开发中遇到问题.. 问题的描 ...
- spring 事物的一些理解
推荐一个我认为Spring事物写得很好的文章. 文章链接:http://www.codeceo.com/article/spring-transactions.html 文章作者:码农网 – 吴极心 ...
- spring事物的管理方式
Spring事务配置的五种方式 转载大神总结: https://blog.csdn.net/xuanjiewu/article/details/51604967: 自己总结:这里只总结spring编程 ...
- Spring事物管理简介 (转)
一.事物1.什么是事物 事物指的是逻辑上的一组操作,这组操作要么全部成功,要么全部失败 2.事物的特性 原子性:事物是一个不可分割的工作单位,事物中的操作要么都发生,要么都不发生 一致性:事物前后数据 ...
- Java基础(spring事物和锁)
使用步骤: 步骤一.在spring配置文件中引入<tx:>命名空间<beans xmlns="http://www.springframework.org/schema/b ...
- Spring事物
简介 Spring并不直接管理事务,而是提供了多种事务管理器,他们将事务管理的职责委托给Hibernate或者JTA等持久化机制所提供的相关平台框架的事务来实现. Spring事务管理器的接口是org ...
- struts2与spring集成时action的class属性值意义
struts2单独使用时action由struts2自己负责创建:与spring集成时,action实例由spring负责创建(依赖注入).这导致在两种情况下struts.xml配置文件的略微差异. ...
随机推荐
- 配置VsCode的QT工程
配置VsCode的QT工程 VsCode + qmake 环境(Environment): Windows11 Qt5.12.11+ MinGW64 编译套件 VsCode (version = 1. ...
- Linux 调用约定
函数调用约定是对函数调用时如何传递参数的一种约定.关于它的约定有许多种,下面我们分 别从内核接口和用户接口两方面介绍32位和64位Linux的调用约定. 一.内核接口 x86-32系统调用约定 ...
- gitlab docker升级报错
背景 使用docker部署gitlab(9.5.4)后,发现合并代码有问题 日志: 看gitlab官网此问题已修复,由于上传了一批代码,又懒得重建,决定对gitlab升级 docker启动命令: do ...
- 一文了解Go语言的匿名函数
1. 引言 无论是在Go语言还是其他编程语言中,匿名函数都扮演着重要的角色.在本文中,我们将详细介绍Go语言中匿名函数的概念和使用方法,同时也提供一些考虑因素,从而帮助在匿名函数和命名函数间做出选择. ...
- 未来的编程语言「GitHub 热点速览」
又一个编程语言火了,不算新,因为它已经开发了一段时间.不过在本周 Hacker News 上风头十足,DreamBerd 除了有点意思的改 ; 分隔符为 !,之外,它还能让你用问号来标注一段你也不确定 ...
- 2021/1/10例会 academy of management journal 2014vol 57 No.2,484-514
这次的论文由于考试周的原因看的不是很细,但大概还是浏览过一遍了.然后这次我的拓展又神奇的匹配到了教授想让我们接下来想看的论文. perfect! 但不足的是,没有进行相关论文的检索,自己的拓展没有理论 ...
- 谷歌语法的基础知识&FOFA
谷歌语法 谷歌语法基础符号: "xxx":表示完全匹配,即关键字不能分开,顺序也不能变 +:"xxx"+www.baidu.com 搜索xxx与baidu.c ...
- Codeforces Round #880 (Div. 2) A-D
A 代码 #include <bits/stdc++.h> using namespace std; using ll = long long; int cnt[107]; bool so ...
- C++与Java的API对比(集合操作等方面)
转载请注明出处(- ̄▽ ̄)- 个人第一篇博客,觉得不错就点个"推荐"吧 φ(゜▽゜*)♪ 虽然自己是先学的C++,再学的Java,但是相对而言,自己写Java比写C++要相对多一些 ...
- Seal AppManager v0.2 发布:进一步简化应用部署体验
经过近3个月的研发,Seal AppManager v0.2 已正式发布. Seal AppManager 是一款基于平台工程理念的应用统一部署管理平台,于今年4月首次推出.在上一版本中,我们已经释出 ...