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


猜你喜欢
- 看如下代码#include "pch.h"#include <iostream>using namespac
- 本文实例讲述了java可变参数当做数组处理的方法.分享给大家供大家参考,具体如下:java可变参数当做数组处理ava1.5增加了新特性:可变
- 一、前言 接触面向对象的思想已经有一段时光了,为什么要学习面向对象呢
- 本文较为详细的总结分析了Android编程下拉菜单spinner用法。分享给大家供大家参考,具体如下:Spinner控件也是一种列表类型的控
- 前几天刚好有需求要把emoji对应的Unicode编码转换成文字,比如1f601对应的这个笑脸😁,但没有找到C#的把1f601转换成文字的方
- 堆排序基本介绍1、堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),
- 一段看似平平无奇的代码Classroom classroom = this.getOne( Wrappers.<Class
- 本文实例为大家分享了C#超市收银系统设计的具体代码,供大家参考,具体内容如下1.登录界面代码如下:using System;using Sy
- 单例模式算是设计模式中最容易理解,也是最容易手写代码的模式,但是其中涉及的知识点却一点也不少,所以经常作为面试题来考。一般单例都是五种写法:
- 序言在flutter开发中,我们使用 bloc 框架,基于状态变更进行响应式开发。本篇文章,小轰将 bloc 核心业务块进行拆解简化,聊一聊
- 一、新建短信微服务1、在service模块下创建子模块service-msm2.创建controller和service代码3.配置appl
- 这里以list为介绍:private static readonly T[] s_emptyArray = new T[0];public
- C#中List<T>中泛型T如果是一个对象的话,则利用Find函数返回的将是这个对象的指针,对其返回对象的属性进行操作,也会影响
- using System; using System.Management; namespace
- bufferedReader.readLine()读到最后发生阻塞最近在做一个imageserver,需求简化后就是使用socket响应HT
- 最近在开发的过程中,遇到了一个需要截取屏幕保存为图片的需求,具体为截取webview的视图保存图片。方法1:首先想到的思路是利用SDK提供的
- 本文实例为大家分享了Java实现坦克大战小游戏的具体代码,供大家参考,具体内容如下创作背景:n年前的学期末课题设计,从b站上学的,一个代码一
- 本文实例讲述了Android应用启动另外一个apk应用的方法。分享给大家供大家参考,具体如下:在开发的过程中,经常会遇到在一个应用中启动另外
- 在c#中怎样调用VC写的OCX控件,主要有两个关键环节两个关键环节:导入ocx控件,创建实例。1 注册ocx:regsvr32.exe al
- 下面的题目都是楼主在android交流群大家面试时遇到的,如果大家有好的题目或者好的见解欢迎分享,楼主将长期维护此帖。某公司高级面试题(20