Spring事务失效原因分析解决
文章目录
在工作中,经常会碰到一些事务失效的坑,基于遇到的情况,以及了解到的坑,写了本篇文章与大家学习交流~
1、方法内部调用
非事务方法调用事务方法会出现问题
@Autowired
private KsAService ksAService;
public void add() {
this.doAdd();
}
@Transactional
public void doAdd() {
KsA ksA = new KsA();
ksA.setName("forlan");
ksAService.insert(ksA);
int res = 1 / 0;
}
原因:Spring声明式事务是基于动态代理(AOP)实现的对bean的管理和切片,为我们每个class生成代理对象,只有代理对象之间调用,才会触发切面逻辑,方法A调用方法B,这里的ksAService是真实对象,不是代理对象
解决:
- add方法加上注解@Transactional
- doAdd方法中使用代理对象来调用
@Transactional
public void doAdd() {
KsA ksA = new KsA();
ksA.setName("forlan");
KsAService ksAService =(KsAService) AopContext.currentProxy();
ksAService.insert(ksA);
int res = 1 / 0;
}
2、修饰符
@Transactional
private void doAdd() {
KsA ksA = new KsA();
ksA.setName("forlan");
ksAService.insert(ksA);
int res = 1 / 0;
}
原因:Spring声明式事务是基于动态代理实现
- 非public修饰,不能被代理
- static修饰的方法属于类,不属于对象,不能被重写,不能被代理
- final修饰的方法不能被重写,不能被代理
解决:不使用这些修饰符,非public、static、final
- static、final,代理里面一般有提示,Methods annotated with ‘@Transactional’ must be overridable
- 注意不要使用非public修饰,特别是private,我们很习惯性写成这个
3、非运行时异常
@Transactional
public void doAdd() throws IOException{
KsA ksA = new KsA();
ksA.setName("forlan");
ksAService.insert(ksA);
throw new IOException();
}
原因:使用Spring的@Transactiona开启事务,默认Error和RuntimeException及其子类才会回滚
解决:指定异常回滚@Transactional(rollbackFor = Exception.class)
4、try…catch捕获异常
@Transactional
public void doAdd() throws RuntimeException {
KsA ksA = new KsA();
ksA.setName("forlan");
ksAService.insert(ksA);
try {
int res = 1 / 0;
} catch (Exception e) {
// 抛出异常
// 设置手动回滚
}
}
原因:自己捕获了异常,则事务无法感知
解决:
- 抛出异常:throw new RuntimeException(e.getMessage());
- 设置手动回滚:TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
5、多线程调用
@Transactional
public void doAdd() {
new Thread(() -> {
KsA ksA = new KsA();
ksA.setName("forlan");
ksAService.insert(ksA);
}).start();
int res = 1 / 0;
}
原因:因为Spring的事务是通过数据库连接来实现不同线程使用不同的数据库连接,放在ThreadLocal中,基于同一数据库连接的事务才能同时提交或回滚,多线程场景下,拿到的数据库连接是不一样的
解决:
- 分布式事务保证
- 自己实现事务回滚
6、同时使用@Transactional和@Async
A类事务方法调用B类异步方法
public class A{
@Transactional
public void add() {
KsA ksA = new KsA();
ksA.setName("forlan");
ksAService.insert(ksA);
}
}
public class B{
@Async
public void insert(KsA ksA) {
this.ksADao.insert(ksA);
int res = 1 / 0;
}
}
原因:同多线程调用问题类似,异步方法属于开启一个新线程执行了
解决:
- 异步方法加上@Transactional
7、错误使用事务传播行为
具体可以了解 Spring事务传播行为实战
比如:使用了@Transactional(propagation = Propagation.NOT_SUPPORTED),(不支持事务)如果当前存在事务,就把当前事务挂起
8、使用的数据库不支持事务
比如,MySQL中的MyISAM,是不支持事务的
原因:Spring事务基于数据库事务实现
9、是否开启事务支持
我们使用的SpringBoot默认开启事务支持了,通过我们引入的依赖jar包,可以发现@EnableTransactionManagement
Spring事务失效原因分析解决的更多相关文章
- spring事务失效情况分析
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt113 <!--[if !supportLists]-->一.&l ...
- Spring事务失效的原因
http://blog.csdn.net/paincupid/article/details/51822599 Spring事务失效的原因 5种大的原因 如使用mysql且引擎是MyISAM,则事务会 ...
- Spring事务失效的2种情况
使用默认的事务处理方式 因为在java的设计中,它认为不继承RuntimeException的异常是”checkException”或普通异常,如IOException,这些异常在java语法中是要求 ...
- java面试记录二:spring加载流程、springmvc请求流程、spring事务失效、synchronized和volatile、JMM和JVM模型、二分查找的实现、垃圾收集器、控制台顺序打印ABC的三种线程实现
注:部分答案引用网络文章 简答题 1.Spring项目启动后的加载流程 (1)使用spring框架的web项目,在tomcat下,是根据web.xml来启动的.web.xml中负责配置启动spring ...
- 8个Spring事务失效的场景,你碰到过几种?
前言 作为Java开发工程师,相信大家对Spring种事务的使用并不陌生.但是你可能只是停留在基础的使用层面上,在遇到一些比较特殊的场景,事务可能没有生效,直接在生产上暴露了,这可能就会导致比较严重的 ...
- oracle 索引失效原因及解决方法
oracle 索引失效原因及解决方法 2010年11月26日 星期五 17:10 一.以下的方法会引起索引失效 1,<>2,单独的>,<,(有时会用到,有时不会)3,like ...
- kubectl get 后按2次tab键命令补全的失效原因分析
kubectl get 后按2次tab键命令补全的失效原因分析 2019/10/28 Chenxin a.bash客户端工具 在centos用户下, cd ~;echo "source &l ...
- Spring事务管理全面分析
Spring 事务属性分析什么是事物 事务管理对于企业应用而言至关重要.它保证了用户的每一次操作都是可靠的,即便出现了异常的访问情况,也不至于破坏后台数据的完整性.就像银行的自助取款机,通常都能正常 ...
- [心得体会]spring事务源码分析
spring事务源码分析 1. 事务的初始化注册(从 @EnableTransactionManagement 开始) @Import(TransactionManagementConfigurati ...
- Spring事务深入剖析--spring事务失效的原因
之前我们讲的分布式事务的调用都是在一个service中的事务方法,去调用另外一个service中的业务方法, 如果在一个sevice中存在两个分布式事务方法,在一个seivice中两个事务方法相互嵌套 ...
随机推荐
- C++初阶(vector容器+模拟实现)
迭代器 四种迭代器 容器类名::iterator 迭代器名;//正向迭代器 容器类名::const_iterator 迭代器名;//常量正向迭代器,const修饰,只能用于读取容器内的元素,不能改变其 ...
- layui的switch监听事件无用
像layui的这种表单事件是属于表单,而不是表格,所以操作是layui.form.on监听事件,而不是用layui.table.on table = layui.table , form = layu ...
- vue 项目中,后端返回文件流,导出excel
之前写过文件流导出excel,这次直接把上次的代码拿过来复制粘贴,但是导出的表格里面没有数据,只显示undefined. 这是之前的代码 // api接口页面 // excel导出接口 export ...
- Android网络请求(2)
Android网络请求(2) 在android网络开发中,除get请求外常见的还有post.put.delete这三种,接下来我们将详细讲解这三种请求及参数 GET请求 我们使用过get请求了,对于我 ...
- MySQL库,表,数据的操作
数据库的操作 1. 创建数据库 create database [if not exists] `数据库名` charset=字符编码(utf8mb4); 如果多次创建会报错 如果不指定字符编码,默认 ...
- supervisor安装与监控nginx
安装参考:https://www.cnblogs.com/zgcblog/p/10192077.html https://www.cnblogs.com/yangbo981205/p/14928897 ...
- 【每日一题】【与运算判断奇偶】【list的重载前后插入】2021年11月25日-103. 二叉树的锯齿形层序遍历
给定一个二叉树,返回其节点值的锯齿形层序遍历.(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行). 例如:给定二叉树 [3,9,20,null,null,15,7], 来源:力扣 ...
- lv逻辑卷
一.逻辑卷的使用 1.逻辑卷的概念 LVM(逻辑卷管理) 适合于管理大存储设备,并允许用户动态调整文件系统的大小.此外,LVM 的快照功能可以帮助我们快速备份数据.LVM 为我们提供了逻辑概念上的磁盘 ...
- 网易云VIP音乐NCM文件转MP3,C语言版本。
前言 网易云的Vip音乐下载下来,格式不是mp3/flac这种通用的音乐格式,而是经过加密的ncm文件.只有用网易云的音乐App才能够打开.于是想到可不可以把.ncm文件转换成mp3或者flac文件, ...
- 用Python来写个小型购物车程序
0x1 前言 Python语言能做很多东西的,像数据分析啊.自动化.开发. 爬虫(真的很棒哟,初学者玩很有成就感的啊哈哈)等等还有挺多. 0x2 用Python编写的一个小型购物车程序 import ...