深入了解 Spring boot的事务管理机制:掌握 Spring 事务的几种传播行为、隔离级别和回滚机制,理解 AOP 在事务管理中的应用

963034f17590412b808770f619144970.png

🎉🎉欢迎光临,终于等到你啦🎉🎉

🏅我是苏泽,一位对技术充满热情的探索者和分享者。🚀🚀

🌟持续更新的专栏《Spring 狂野之旅:从入门到入魔》 🚀

本专栏带你从Spring入门到入魔 

这是苏泽的个人主页可以看到我其他的内容哦👇👇

努力的苏泽http://suzee.blog.csdn.net/

 


 

目录

介绍

1.1 Spring 事务管理的重要性

1.2 目标和范围

Spring 事务基础

2.1 事务概述

2.2 事务管理器

2.3 事务定义和注解

事务角色

事务相关配置

事务传播行为

1. REQUIRED 传播行为

2. REQUIRES_NEW 传播行为

3. SUPPORTS 传播行为

4. NOT_SUPPORTED 传播行为

5. MANDATORY 传播行为

6. NEVER 传播行为

​编辑

隔离级别

1. READ_UNCOMMITTED 隔离级别

2. READ_COMMITTED 隔离级别

3. REPEATABLE_READ 隔离级别

4. SERIALIZABLE 隔离级别

事务原理

aop/动态代理

事务管理

对于编程式事务管理:

对于声明式事务管理:

实例

TransactionInterceptor 事务拦截处理


 

 

 

d0464b6237e94b0a9210f632325218c6.png

介绍

1.1 Spring 事务管理的重要性

在应用程序中,事务管理是确保数据的一致性和完整性的重要组成部分。Spring 事务管理提供了一种可靠且灵活的方式来管理事务,确保在数据库操作过程中的原子性、一致性、隔离性和持久性。

Spring 事务管理的重要性包括:

  • 数据库一致性:通过事务管理,可以确保数据库操作的原子性,即要么所有操作都成功提交,要么全部回滚,从而保持数据的一致性。
  • 错误处理和回滚:事务管理使得在发生错误时能够回滚事务,确保数据的完整性,以及在异常情况下进行适当的错误处理。
  • 并发控制:通过定义适当的隔离级别,事务管理可以处理并发访问数据库的问题,避免数据冲突和不一致性。
  • 扩展性和灵活性:Spring 事务管理提供了多种配置选项和编程方式,可以根据应用程序的需求进行灵活配置和管理。

1.2 目标和范围

Spring 事务管理的目标是确保在应用程序中的数据库操作过程中,能够实现以下目标:

  • 原子性(Atomicity):事务中的所有操作要么全部成功执行并提交,要么全部失败并回滚,确保数据库的一致性。
  • 一致性(Consistency):事务的执行过程中,数据库从一个一致的状态转变为另一个一致的状态,不会破坏数据的完整性。
  • 隔离性(Isolation):多个并发事务之间应该相互隔离,每个事务的操作应该看起来像是在独立执行,避免数据冲突和不一致性。
  • 持久性(Durability):一旦事务提交,其对数据库的修改应该是永久性的,即使在系统故障或重启后也能够恢复。

Spring 事务管理的范围包括:

  • 支持多种事务管理方式:Spring 提供了多种事务管理方式,包括编程式事务管理和声明式事务管理,以适应不同的应用场景和开发需求。
  • 集成多种事务管理器:Spring 可以与各种事务管理器集成,包括本地 JDBC 事务、JTA 分布式事务、Hibernate 事务等,以便与不同的持久化框架和数据库进行交互。
  • 提供注解和 XML 配置支持:Spring 允许使用注解或 XML 配置的方式来定义和管理事务,使得事务管理更加灵活和便捷。

Spring 事务基础

2.1 事务概述

Spring 事务是一组数据库操作的逻辑单元,具有原子性和一致性。事务由一系列操作组成,这些操作要么全部成功执行并提交,要么全部失败并回滚。

Spring 事务的关键概念包括:

  • 事务管理器(Transaction Manager):事务管理器是 Spring 提供的一个接口,用于管理事务的开始、提交和回滚操作。它与底层的数据库或持久化框架进行交互,并确保事务的正确执行。
  • 事务定义(Transaction Definition):事务定义定义了事务的属性,如隔离级别、传播行为、超时设置等。它可以通过编程方式或声明式方式来定义。
  • 事务状态(Transaction Status):事务状态表示当前事务的状态,包括已提交、已回滚或进行中等。通过事务状态,可以对事务进行管理和控制。
  • 事务切面(Transaction Aspect):事务切面是应用程序中与事务相关的逻辑和功能的集合。它可以通过编程方式或声明式方式来定义和应用。

2.2 事务管理器

在 Spring 中,事务管理器(Transaction Manager)是用于管理事务的关键组件。事务管理器负责事务的开始、提交和回滚操作,并与底层的数据库或持久化框架进行交互。

Spring 提供了多种事务管理器的实现,包括:

  • DataSourceTransactionManager:用于管理基于 JDBC 的事务,与 JDBC DataSource 进行交互。
  • JpaTransactionManager:用于管理基于 JPA(Java Persistence API)的事务,与 JPA EntityManagerFactory 进行交互。
  • HibernateTransactionManager:用于管理基于 Hibernate 的事务,与 Hibernate SessionFactory 进行交互。
  • JtaTransactionManager:用于管理分布式事务,与 JTA(Java Transaction API)进行交互。

你可以根据应用程序所使用的持久化框架选择合适的事务管理器。

2.3 事务定义和注解

在 Spring 中,事务定义(Transaction Definition)用于定义事务的属性,如隔离级别、传播行为、超时设置等。事务定义可以通过编程方式或声明式方式来定义。

编程式事务定义是通过编写代码来显式地管理事务的开始、提交和回滚。你可以使用编程式事务管理的 API(如 TransactionTemplate)来定义事务的属性。

声明式事务定义是通过在方法或类级别上使用注解或 XML 配置来定义事务的属性。Spring 提供了 @Transactional 注解,用于在方法级别上定义事务的属性。你可以在需要进行事务管理的方法上添加 @Transactional 注解,并指定事务的属性。

事务的属性包括传播行为(Propagation)、隔离级别(Isolation)、只读标志(ReadOnly)、超时设置(Timeout)等。通过定义适当的事务属性,你可以控制事务的行为和特性。

例如,下面是一个使用 @Transactional 注解定义事务的例子:

@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT)
public void performTransaction() {
    // 事务操作
}

事务角色

e36f40795cd34803a141d0149cef5b88.png

 

d3e9cdff426246fda0e4d8135e3e3f66.png

事务相关配置

0f200c92b8d04c439a5eb80159c968dd.png

 

事务传播行为

1. REQUIRED 传播行为

  • 如果当前存在事务,则加入该事务中执行。
  • 如果当前没有事务,则创建一个新的事务执行。
  • 这是Spring默认的传播行为。

2. REQUIRES_NEW 传播行为

  • 总是创建一个新的事务,并挂起当前事务(如果存在)。
  • 在新的事务中执行方法,不受外部事务的影响。

3. SUPPORTS 传播行为

  • 如果当前存在事务,则加入该事务中执行。
  • 如果当前没有事务,则以非事务的方式执行。

4. NOT_SUPPORTED 传播行为

  • 总是以非事务的方式执行方法。
  • 如果当前存在事务,则将其挂起。

5. MANDATORY 传播行为

  • 如果当前存在事务,则加入该事务中执行。
  • 如果当前没有事务,则抛出异常。

6. NEVER 传播行为

  • 总是以非事务的方式执行方法。
  • 如果当前存在事务,则抛出异常。

e1788f2dc372458da5ccc9a553a6a9b8.png

 832a99a3239f47bbb2e16138ca06af85.png

 

 

隔离级别

1. READ_UNCOMMITTED 隔离级别

  • 最低的隔离级别,允许脏读、不可重复读和幻读的发生。
  • 一个事务可以读取另一个事务未提交的数据。

2. READ_COMMITTED 隔离级别

  • 保证一个事务修改的数据提交后才能被另一个事务读取。
  • 避免脏读的发生,但仍可能出现不可重复读和幻读。

3. REPEATABLE_READ 隔离级别

  • 保证一个事务不能读取另一个事务未提交的数据。
  • 避免脏读和不可重复读的发生,但仍可能出现幻读。

4. SERIALIZABLE 隔离级别

  • 最高的隔离级别,保证所有情况下都不会发生脏读、不可重复读和幻读。
  • 事务被处理为顺序执行,避免并发读写操作。

ae1c3b8ddbe1497090e04ee82f14532a.png

 

事务原理

aop/动态代理

Spring的事务抽象包括三个主要接口:PlatformTransactionManager、TransactionDefinition和TransactionStatus。

  • PlatformTransactionManager负责定义事务的边界,它确定了何时开始和结束一个事务。
  • TransactionDefinition负责定义事务的属性,包括隔离级别、传播行为等。它提供了对事务进行详细配置的能力。
     
  • PlatformTransactionManager根据TransactionDefinition的属性定义来开启相关的事务。在事务开始后到结束期间,TransactionStatus负责跟踪和管理事务的状态。通过TransactionStatus,我们可以对事务进行有限的控制。
     
  • 常用的TransactionDefinition的实现包括DefaultTransactionDefinition和TransactionTemplate。这两个主要用于编程式事务场景。另外,还有DefaultTransactionAttribute和RuleBasedTransactionAttribute,它们主要用于基于Spring AOP的声明式事务管理场景。RuleBasedTransactionAttribute允许同时指定多个回滚规则。
     
  • TransactionStatus的一个常见实现是DefaultTransactionStatus,它用于记录事务的状态信息。
  • PlatformTransactionManager的实现可以分为面向局部事务和面向全局事务两个分支。常用的面向局部事务的实现包括DataSourceTransactionManager(用于JDBC和MyBatis)和HibernateTransactionManager。它们提供了针对特定持久化框架的事务管理功能。

6ce87c644e4546a79469c312e014ecc4.png

 

035dd59c8c9f4290882eb7da28f91778.png

 

事务管理

对于编程式事务管理:

  1. 使用TransactionTemplate或直接使用底层的PlatformTransactionManager进行操作。
  2. 需要在代码中显式地编写事务管理的逻辑。
  3. 需要手动处理事务的开始、提交和回滚。
  4. 事务的管理逻辑与业务逻辑紧密耦合,导致代码的可读性和可维护性降低。
  5. 可以在更细粒度的代码块级别实现事务管理。

对于声明式事务管理:

  1. 建立在AOP(面向切面编程)之上,通过拦截目标方法前后的执行来实现事务管理。
  2. 通过配置文件或基于@Transactional注解的方式声明事务规则。
  3. 不需要在业务逻辑代码中编写事务管理的代码,保持业务代码的纯粹性。
  4. 事务的管理逻辑与业务逻辑解耦,提高了代码的可读性和可维护性。
  5. 最细粒度只能作用于方法级别,无法直接作用于代码块级别,但可以通过方法的粒度来实现类似的效果。

 

 

实例

假设我们有一个银行账户系统,其中涉及两个账户之间的转账操作,需要保证转账操作的原子性,即要么两个账户的金额同时发生变化,要么都不发生变化。

首先,我们需要使用数据库事务来确保转账操作的一致性。假设我们使用Spring框架来管理事务,代码如下所示:

@Transactional
public void transferAmount(String fromAccount, String toAccount, double amount) {
    try {
        // 1. 查询转出账户的余额
        double fromBalance = accountDao.getBalance(fromAccount);

        // 2. 查询转入账户的余额
        double toBalance = accountDao.getBalance(toAccount);

        // 3. 判断转出账户余额是否足够
        if (fromBalance < amount) {
            throw new InsufficientBalanceException("Insufficient balance in the source account.");
        }

        // 4. 扣除转出账户的金额
        accountDao.updateBalance(fromAccount, fromBalance - amount);

        // 5. 增加转入账户的金额
        accountDao.updateBalance(toAccount, toBalance + amount);

        // 6. 提交事务
    } catch (Exception e) {
        // 7. 出现异常,回滚事务
        throw new TransferException("Error occurred during the transfer.", e);
    }
}

我们使用@Transactional注解表示该方法需要在事务中执行。在方法内部,我们按照以下步骤进行转账操作:

  1. 查询转出账户的余额。
  2. 查询转入账户的余额。
  3. 判断转出账户余额是否足够,如果不足够,则抛出异常。
  4. 扣除转出账户的金额。
  5. 增加转入账户的金额。

在第6步之前,如果发生了异常,会跳转到第7步,即异常处理的代码块。在异常处理块中,我们抛出一个自定义的TransferException,并使用throw语句将异常继续抛出。这会触发Spring事务管理器的回滚机制,导致之前的数据库操作被撤销,从而恢复到事务开始之前的状态。

通过事务回滚机制,如果在转账过程中发生异常,例如转出账户余额不足,所有的数据库操作都会被回滚,确保数据的一致性。这样可以避免转账过程中数据发生不一致的情况。

TransactionInterceptor 事务拦截处理

通过 Pointcut 事务切点筛选出来的 Bean,会创建一个代理对象,Bean 内部肯定定义了 @Transactional 注解,如果是类上定义的 @Transactional 注解,每个方法都需要进行事务处理。代理对象的事务拦截处理在 TransactionInterceptor 拦截器中,实现了 MethodInterceptor 方法拦截器,也就是实现了 Object invoke(MethodInvocation invocation) 这个方法,一起来看看 TransactionInterceptor 这个类

8e44f9e7b65644a5871525095bcaab30.png

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/466549.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

深圳女游客山顶拍照不慎跌落,幸得及时救助无大碍。

深圳排牙山近日发生了一起惊险的意外事件。一名女游客在龟仙石打卡拍照时&#xff0c;因手滑不慎从石头上跌落&#xff0c;幸运的是&#xff0c;周围的游客迅速反应&#xff0c;合力接住了她&#xff0c;避免了更严重的后果。 据了解&#xff0c;这位女游客在攀爬龟仙石时&…

Dagger2相关知识

目录 一、Dagger简介1.1 什么是Dagger?1.2 Dagger用来干什么&#xff1f;1.3 使用Dagger2注入对象1.4 Dagger注解 二、Dagger2使用2.1 非单例2.2 局部单例2.3 全局单例 三、参考链接 一、Dagger简介 1.1 什么是Dagger? Dagger 2 是一个由 Google 开发的依赖注入框架&#x…

HTML + CSS 核心知识点- 定位

简述&#xff1a; 补充固定定位也会脱离文档流、不会占据原先位置 1、什么是文档流 文档流是指HTML文档中元素排列的规律和顺序。在网页中&#xff0c;元素按照其在HTML文档中出现的顺序依次排列&#xff0c;这种排列方式被称为文档流。文档流决定了元素在页面上的位置和互相之…

【图论】树链剖分

本篇博客参考&#xff1a; 【洛谷日报#17】树链剖分详解Oi Wiki 树链剖分 文章目录 基本概念代码实现常见应用路径维护&#xff1a;求树上两点路径权值和路径维护&#xff1a;改变两点最短路径上的所有点的权值求最近公共祖先 基本概念 首先&#xff0c;树链剖分是什么呢&…

centos7.9的GUI桌面样式不符合默认熟悉的操作习惯

一、问题描述&#xff1a; 原因&#xff1a;桌面样式选错了。 二、解决&#xff1a; 1.先登进去LogOut。 2.点击设置的工具图标中的GNOME Classic即可恢复成默认操作习惯的桌面样式。 3.恢复到默认熟悉的操作界面

基于有限状态机开发健壮的Nodejs/TCP客户端

有限状态机是一种数学计算模型&#xff0c;它描述了在任何给定时间只能处于一种状态的系统的行为。形式上&#xff0c;有限状态机有五个部分&#xff1a; 初始状态值 (initial state)有限的一组状态 (states)有限的一组事件 (events)由事件驱动的一组状态转移关系 (transition…

浏览器如何查看http请求的报文?

HTTP协议用于从WWW服务器传输超文本到本地浏览器的传送协议。 它可以使浏览器更加高效&#xff0c;使网络传输减少。 它不仅保证计算机正确快速地传输超文本文档&#xff0c;还确定传输文档中的哪一部分&#xff0c;以及哪部分内容首先显示 (如文本先于图形)等。所以在node.js里…

viple拓展题

数数问题 题目&#xff1a;使用viple来实现程序&#xff0c;使得运行结果能将数字逐个数出即可 思路&#xff1a;首先&#xff0c;数数字&#xff0c;不知道用户具体要求数到多少结束&#xff0c;所以&#xff0c;可以采用简单的对话活动来实现与用户的交互。其次&#xff0c;…

Linux系统安装1Panel管理面板并实现无公网IP远程管理本地服务器

文章目录 前言1. Linux 安装1Panel2. 安装cpolar内网穿透3. 配置1Panel公网访问地址4. 公网远程访问1Panel管理界面5. 固定1Panel公网地址 前言 1Panel 是一个现代化、开源的 Linux 服务器运维管理面板。高效管理,通过 Web 端轻松管理 Linux 服务器&#xff0c;包括主机监控、…

string类型的使用以及编码方式

Redis 中所有的键的类型都是字符串类型&#xff0c;⼀个字符串的最⼤值不能超过 512 MB。 由于 Redis 内部存储字符串完全是按照⼆进制流的形式保存的&#xff0c;所以 Redis 是不处理字符集编码问题的&#xff0c;客⼾端传⼊的命令中使⽤的是什么字符集编码&#xff0c;就存储…

放在你后口袋里的七种基本质量工具

以下是我反复看到的七种质量改进工具。这些质量工具中的大多数已经存在了一段时间&#xff0c;但这肯定不会降低它们的价值&#xff01; 这些工具最大的优点是使用非常简单&#xff0c;并且可以在中快速使用Minitab统计软件或者从事&#xff0c;但你当然可以使用其他方法&…

【已解决】MySQL:常用的除法运算+精度处理+除数为0处理

目录 问题现象&#xff1a; 问题分析&#xff1a; 拓展&#xff1a; 1、除法运算&#xff1a; 拓展&#xff1a;MySQL中常用的几种除法运算 1、取整除法 2、浮点数除法 3、取余除法 4、向上取整除法 5、向下取整除法 2、运算结果的精度处理 1.1、浮点数 1.2、总位数 1.3、…

c++的const总结(转)

为什么使用const&#xff1f;采用符号常量写出的代码更容易维护&#xff1b;指针常常是边读边移动&#xff0c;而不是边写边移动&#xff1b;许多函数参数是只读不写的。const最常见用途是作为数组的界和switch分情况标号(也可以用枚举符代替)&#xff0c;分类如下&#xff1a;…

什么是网站?为什么要搭建网站?

网站&#xff1a;简单来说&#xff0c;网站就是通过互联网来展示信息的页面集合。它可以在电脑或者手机上打开&#xff0c;提供各种功能&#xff0c;比如查看新闻、购买商品、搜索信息等。 一、建网站的目的&#xff1a;展示个人或企业的存在 网站建设的首要目的之一是展示个人…

十年追光者 | 一段人生故事,聆听《康岛天香》创始人李波的成长历程

​为了响应国家乡村振兴&#xff0c; 绿水青山就是金山银山&#xff0c; 中药材复兴等 国家政策&#xff0c;来自老家河南的李波女士&#xff0c;如今在海南澄迈县桥头镇 开启了她的沉香创业故事&#xff0c; 沉香树一直以来被誉为海南第四颗树&#xff0c; 从最早 20 亩沉香…

java入门 -输入和输出

输入输出 开发中大量会使用输入和输出&#xff0c;今天来总结一下Java语法阶段常使用的输入和输出。 输出 System.out 控制台输出信息。 不换行显示一行&#xff1a; System.out.print( ); System.out.print("hello "); System.out.print("java!");运行结…

JMeter压测SpringBoot项目

压力测试架构图如下: 配置JMeter 在JMeter的bin目录,双击jmeter.bat 新建一个测试计划,并右键添加线程组: 进行配置 一共会发生4万次请求。 ctrl + s保存; 添加http请求: 配置http请求: 配置断言,来判断当前请求是否成功: 正常响应如下:

Tomcat Session ID---会话保持

简单拓补图 一、负载均衡、反向代理 7-1nginx代理服务器配置 [rootdlnginx ~]#yum install epel-release.noarch -y ###安装额外源[rootdlnginx ~]#yum install nginx -y[rootdlnginx ~]#systemctl start nginx.service[rootdlnginx ~]#systemctl status nginx.service [ro…

机器人路径规划:基于Bug算法的机器人路径规划(提供Python代码)

一、Bug算法简介 Bug 算法是一种基于追踪障碍物的路径规划算法&#xff0c;它模拟了一种昆虫寻找巢穴的行为&#xff0c;因此得名Bug算法。Bug算法的基本思路是&#xff1a;当机器人遇到障碍物时&#xff0c;他会沿着障碍物的边缘行走&#xff0c;直到到达目标点。该算法可以分…