Spring中事务几个常见的问题解决
作者:时光清浅ぴ许你安然 时间:2022-04-07 00:52:01
前言
首先,事务这个概念是数据库层面的,Spring只是基于数据库中的事务进行扩展,以及提供了一些能让程序员更新方便操作事务的方式
Spring如何处理事务
Spring中支持编程式事务和声明式事务管理两种方式
1、编程式事务,可以使用TransactionTemplate
public class B {
@Autowired
private TransactionTemplate template;
public void sout(){
TransactionCallback<Integer> transactionCallback = new TransactionCallback<Integer>() {
@Override
public Integer doInTransaction(TransactionStatus transactionStatus) {
//jdbcTemplate.update
//jdbcTemplate.update
if(执行失败){
//回滚事务
transactionStatus.setRollbackOnly();
return -1;
}
return 1;
}
};
Integer result = template.execute(transactionCallback);
}
当加了@Transactional注解后,Spring会基于这个类生成一个代理对象,会将这个代理对象作为bean,当在使用这个代理对象的方法时,如果这个方法上存在@Transactional注解,那么代理逻辑会先把事务的自动提交设置为false,然后再去执行原本的业务逻辑方法,如果执行业务逻辑方法没有出现异常,那么代理逻辑中就会将事务提交,如果执行业务逻辑方法出现了异常,那么会将事务进行回滚。
好处:代码级别的事务控制,可以自己控制事务的逻辑,比较灵活
缺点:太麻烦,需要自己实现所有的事务逻辑
2、声明式事务
是Spring在AOP基础上提供的事务实现机制。
public class B {
@Autowired
private TransactionTemplate template;
@Transactional
public void sout(){
System.out.println("=================A=====================");
}
}
优点:不需要在业务代码中添加事务管理的代码,只需要在配置文件中做相关的事务规则声明规则就可以了。
缺点:只能只能针对方法级别,无法控制代码级别。
Spring事务传播机制
Propagation:多个事务方法相互调用时,事务是如何在这些方法键传播
方法A是一个事务方法。方法A在执行的过程中调用了方法B,那么方法B有无事务以及方法B对事物的要求不同都会对方法A的事务具体执行造成影响,同时方法A的事务对方法B的事务执行也有影响。这种影响具体是什么就由两个方法所定义的事务传播类型所决定
a调用b,以下描述,当前均只a,自己均指b
REQUIRED(Spring默认的事务传播类型):如果当前没有事务,则自己新建一个事务,如果当前存在事务,则加入这个事务。
SUPPORTS:当前存在事务,则加入当前事务,如果当前没有事务,就以非事务方法执行
MANDATORY:当前存在事务,则加入当前事务,如果当前没有事务,则抛出异常
REQUIRES_NEW:创建一个新事务,如果存在当前事务,则挂起该事务(互不干扰)
NOT_SUPPORTED:以非事务方法执行,如果当前存在事务,则挂起当前事务。
NEVER:不使用事务,如果当前存在事务,则抛出异常
NESTED:如果当前存在事务,则嵌套事务中执行,否则REQUIRED操作一样(开启一个事务)
和REQUIRES_NEW的区别:
REQUIRES_NEW是新建一个事务,并且新开启的事务与原事务无关,而NESTED则是当前存在事务时(我们把当前事务成为父事务)会开启一个嵌套事务(称之为一个子事务)。在NESTED情况下父事务回滚时,子事务也会回滚,而在REQUIRES_NEW情况下,原有事务回滚,不会影响新开启的子事务。
和REQUIRED的区别:
REQUIRED情况下,调用方存在事务时,则被调用和调用方法使用同一事务,那么被调用方出现异常时,由于共用一个事务,所以无论调用方法是否catch异常,事务都会回滚(父子事务一起回滚),而在NESTED情况下,被调用方发生异常时,调用发可以catch其异常,这样只有子事务回滚,父事务不受影响(父事务是否需要回滚可以自行决定)
Spring事务隔离级别
ISOLATION:Spring的事务隔离级别
DEFAULT:使用数据库默认的事务隔离级别
READ_UNCOMMITTED:读未提交,允许事务在执行过程中,读取其他事务未提交的数据
READ_COMMITTED:读已提交,允许事务在执行过程中,读取其他事务已提交的数据
REPEATABLE_READ:可重复读,在同一个事务内,任意时刻的查询结果是一致的
SERIALIZABLE:所有事务依次执行
数据库配置的隔离级别是read commited,而spring配置的隔离级别是repeatable read,这个时候隔离级别以哪个为准?
以Spring为准(spring配置的会覆盖数据库的隔离级别),如果Spring配置的隔离级别数据库不支持,效果取决于数据库
来源:https://blog.csdn.net/sxl123sxl/article/details/126109796
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
Java+Nginx实现POP、IMAP、SMTP邮箱代理服务
![](https://img.aspxhome.com/file/2023/7/59327_0s.jpg)
java 字段值为null,不返回该字段的问题
Java编程中的4种代码块详解
SpringBoot用@Async注解实现异步任务
![](https://img.aspxhome.com/file/2023/0/67100_0s.png)
springcloud项目占用内存好几个G导致服务器崩溃的问题
![](https://img.aspxhome.com/file/2023/6/61236_0s.png)
Java实现SSL双向认证的方法
![](https://img.aspxhome.com/file/2023/0/58090_0s.jpg)
详解Java中的线程池
![](https://img.aspxhome.com/file/2023/9/59369_0s.png)
java编写ftp下载工具
Java多线程通信:交替打印ABAB实例
详解Android Flutter中SliverAppBar的使用教程
![](https://img.aspxhome.com/file/2023/7/97867_0s.jpg)
springboot集成mybatisplus的方法
![](https://img.aspxhome.com/file/2023/9/64479_0s.png)
Spring BeanFactory和FactoryBean有哪些区别
解决javaWEB中前后台中文乱码问题的3种方法
![](https://img.aspxhome.com/file/2023/7/64807_0s.jpg)
Mybatis分页插件使用方法详解
Java 自定义注解的魅力
![](https://img.aspxhome.com/file/2023/6/65776_0s.png)
C语言实现两个矩阵相乘
![](https://img.aspxhome.com/file/2023/6/103076_0s.png)
Java框架---Spring详解
![](https://img.aspxhome.com/file/2023/5/61825_0s.jpg)
Spring Boot Thymeleaf实现国际化的方法详解
![](https://img.aspxhome.com/file/2023/8/59008_0s.png)