Spring 核心技术解析【纯干货版】- VIII:Spring 数据访问模块 Spring-Tx 模块精讲

在企业级开发中,事务管理是保障数据一致性和完整性的重要手段。Spring 作为 Java 生态中广泛使用的框架,其事务管理模块(Spring-Tx)不仅提供了强大的功能,还极大地简化了开发者在不同技术栈中的事务处理工作。无论是编程式事务,还是声明式事务,Spring 都以其灵活性和易用性满足了各种场景需求。

本篇文章将从理论到实践,深入解析 Spring-Tx 模块的核心技术与使用方式,并通过代码示例帮助您更高效地掌握事务管理。希望通过本篇内容,您能对 Spring 的事务管理有一个全面且深入的理解。


文章目录
      • 1、Spring-Tx 模块介绍
        • 1.1、Spring-Tx 模块概述
        • 1.2、Spring-Tx 模块依赖
        • 1.3、Spring-Tx 模块作用
      • 2、事务介绍
      • 3、Spring 事务
        • 3.1、Spring 编程式事务
          • 3.1.1、通过 PlatformTransactionManager 控制事务
          • 3.1.2、通过 TransactionTemplate 控制事务
        • 3.2、Spring 声明式事务
          • 3.2.1、声明式事务
          • 3.2.2、@Transactional 注解的使用
          • 3.2.3、事务的传播行为 - Propagation
          • 3.2.4、事务的隔离级别-Isolation
      • X、后记

1、Spring-Tx 模块介绍
1.1、Spring-Tx 模块概述

Spring Tx 模块,是 Spring 中处理事务管理的模块,其中 TX 全称为 Spring Transaction Management。

Spring Tx 模块的设计目标是为了让应用程序中的事务管理变得更加简单、统一和灵活。不论是在传统的 JDBC 环境下,还是在使用 ORM(如 Hibernate)的环境中,它都能提供一致的编程模型来处理事务。

1.2、Spring-Tx 模块依赖

Spring-Tx 模块的依赖有两个,分别是 Spring-Beans 模块和 Spring-Core 模块。

其中 Spring Beans 模块是对 Spring Bean 进行定义,实现 IOC 基础功能的模块。而 Spring-Core 是 Spring 中的基础模块,它提供了框架运行所必需的核心功能。

需要注意的是,Spring-Tx 对事务的实现主要基于 Spring AOP 的原理,但是其本身并不依赖于 Spring 相关 AOP 模块的实现,而是通过自身达成这一效果的。

1.3、Spring-Tx 模块作用

Spring-Tx 模块为开发者提供了一套高效、灵活的事务处理机制,适用于各种持久化技术和事务场景。


2、事务介绍

概括来讲,事务是一个由有限操作集合组成的逻辑单元。事务操作包含两个目的,数据一致以及操作隔离。数据一致是指事务提交时保证事务内的所有操作都成功完成,并且更改永久生效;事务回滚时,保证能够恢复到事务执行之前的状态。操作隔离则是指多个同时执行的事务之间应该相互独立,互不影响。

事务是一个比较广泛的概念,事务管理资源除了我们熟知的数据库外,还可以包含消息队列、文件系统等。当然,一般来说,我们说的事务单指"数据库事务"。


3、Spring 事务

Spring 事务有编程式事务和声明式事务两种实现方式:

  • 编程式事务是通过编写代码来管理事务的提交、回滚、以及事务的边界。这意味着开发者需要在代码中显式地调用事务的开始、提交和回滚。
  • 声明式事务是通过配置来管理事务,您可以使用注解或XML配置来定义事务的边界和属性,而无需显式编写事务管理的代码。
3.1、Spring 编程式事务

编程式事务就是通过硬编码的方式使用 Spring 中提供的事务相关的类来控制事务。主要有 2 种用法:

  • 方式1:通过 PlatformTransactionManager 控制事务
  • 方式2:通过 TransactionTemplate 控制事务
3.1.1、通过 PlatformTransactionManager 控制事务

这种是最原始的方式,代码量比较大,后面其他方式都是对这种方式的封装。这种方式需要手动管理事务的定义、开启、提交和回滚。它的优点是灵活性高,但代码相对繁琐。

示例代码:

import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;public class TransactionService1 {private final PlatformTransactionManager transactionManager;public TransactionService1(PlatformTransactionManager transactionManager) {this.transactionManager = transactionManager;}public void executeTransaction() {// 创建事务定义TransactionDefinition def = new DefaultTransactionDefinition();// 开启事务TransactionStatus status = transactionManager.getTransaction(def);try {// 业务逻辑performBusinessLogic();// 提交事务transactionManager.commit(status);} catch (Exception e) {// 出现异常,回滚事务transactionManager.rollback(status);throw e;}}private void performBusinessLogic() {// 模拟业务逻辑System.out.println("Executing business logic...");// 模拟异常if (true) {throw new RuntimeException("Error occurred");}}
}

优缺点:

  • 优点:灵活性高,适合对事务有特殊控制需求的场景。
  • 缺点:代码量多,增加复杂性,容易遗漏回滚或提交操作。
3.1.2、通过 TransactionTemplate 控制事务

TransactionTemplate 是 Spring 提供的事务管理工具类,它封装了事务的开启、提交和回滚逻辑,简化了代码。开发者只需关注业务逻辑的实现。

示例代码:

import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;public class TransactionService2 {private final TransactionTemplate transactionTemplate;public TransactionService2(TransactionTemplate transactionTemplate) {this.transactionTemplate = transactionTemplate;}public void executeTransaction() {// 使用 TransactionTemplate 执行事务transactionTemplate.execute((TransactionCallback<Void>) status -> {// 业务逻辑performBusinessLogic();return null; // 返回结果,如果有返回值需要修改 Void 类型});}private void performBusinessLogic() {// 模拟业务逻辑System.out.println("Executing business logic...");// 模拟异常if (true) {throw new RuntimeException("Error occurred");}}
}

优缺点:

  • 优点:代码简洁,开发者无需手动管理事务的提交和回滚。
  • 缺点:灵活性比直接使用 PlatformTransactionManager 略低。
3.2、Spring 声明式事务
3.2.1、声明式事务

声明式事务是指使用注解或xml配置的方式来控制事务的提交和回滚。开发者只需要添加配置即可,具体事务的实现由第三方框架实现,避免我们直接进行事务操作。

Spring 提供了 @EnableTransactionManagement 注解在配置类(启动类)上启用支持事务,此时 Spring 会自动扫描具有 @Transactional 注解的类和方法。该注解相当于 xml 配置方式的 <tx:annotation-driven />。通过设置 mode 属性,决定使用 Spring 代理,还是 ASPECTJ 扩展。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {boolean proxyTargetClass() default false;AdviceMode mode() default AdviceMode.PROXY; // 代理模式int order() default Ordered.LOWEST_PRECEDENCE; // LOWEST_PRECEDENCE最低优先级,所以在执行链的最外面,而自己实现的AOP拦截器优先级都高于事务,所以被嵌套在里面,越贴近业务代码。
}
3.2.2、@Transactional 注解的使用

@Transactional 注解可以应用于类和方法 。声明类时,该注解 默认作用于类和子类的所有方法,应用于 public 方法才有效 ;父类方法要加入同等级别的注解,需要单独声明。

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {@AliasFor("transactionManager")String value() default "";// 用来确定目标事务管理器@AliasFor("value")String transactionManager() default "";// 事务的传播,默认Propagation.REQUIREDPropagation propagation() default Propagation.REQUIRED;// 事务隔离级别,默认是Isolation.DEFAULTIsolation isolation() default Isolation.DEFAULT;// 事务超时时间,默认是-1int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;// 指定事务是否为只读事务,默认为false,仅仅是个提示boolean readOnly() default false;// 标识能触发事务回滚的异常类型,默认是RuntimeException和Error,不包含检查异常。Class<? extends Throwable>[] rollbackFor() default {};// 标识哪些异常不需要回滚事务Class<? extends Throwable>[] noRollbackFor() default {};String[] noRollbackForClassName() default {};String[] rollbackForClassName() default {};
}

其中,isolationtimeout 两个属性仅对新启动的事务有效,专为 Propagation.REQUIREDPropagation.REQUIRES_NEW 使用而设计。

3.2.3、事务的传播行为 - Propagation

Propagation 定义了事务的传播,一共有 7 种级别。

public enum Propagation {REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED),SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS),MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY),REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW),NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED),NEVER(TransactionDefinition.PROPAGATION_NEVER),NESTED(TransactionDefinition.PROPAGATION_NESTED);private final int value;Propagation(int value) {this.value = value;}public int value() {return this.value;}
}
  • REQUIRED :使用当前的事务,如果当前没有事务,则自己新建一个事务,子方法是必须运行在一个事务中的;如果当前存在事务,则加入这个事务,成为一个整体。

  • SUPPORTS :如果当前有事务,则使用事务;如果当前没有事务,则不使用事务。多用于查询。

  • MANDATORY:传播属性强制必须存在一个事务,如果不存在,则会抛出异常。

  • REQUIRES_NEW:如果当前有事务,则挂起该事务,并且自己创建一个新的事务给自己使用;如果当前没有事务,则同 REQUIRED

  • NOT_SUPPORTED:如果当前有事务,则把事务挂起,自己不使用事务运行数据库操作

  • NEVER:如果当前有事务存在,则抛出异常

  • NESTED:如果当前存在事务,则开启子事务(嵌套事务);如果当前没有事务,则同 REQUIRED。但是 如果主事务提交,则会携带子事务一起提交。如果主事务回滚,则子事务会一起回滚。 相反,子事务异常,则父事务可以回滚或不回滚(trycatch)。

3.2.4、事务的隔离级别-Isolation

Isolation 定义了事务的隔离级别,一共有 5 种。

public enum Isolation {DEFAULT(TransactionDefinition.ISOLATION_DEFAULT),READ_UNCOMMITTED(TransactionDefinition.ISOLATION_READ_UNCOMMITTED), READ_COMMITTED(TransactionDefinition.ISOLATION_READ_COMMITTED), REPEATABLE_READ(TransactionDefinition.ISOLATION_REPEATABLE_READ), SERIALIZABLE(TransactionDefinition.ISOLATION_SERIALIZABLE);private final int value;Isolation(int value) {this.value = value;}public int value() {return this.value;}
}

Spring 事务隔离级别共有 5 种,隔离级别的设置依赖当前数据库是否支持。

  • DEFAULT:使用当前数据库的默认隔离级别。例如Oracle是READ_COMMITED,MySQL是READ_REPEATED。
  • READ_UNCOMMITED:可导致脏读、不可重复读、幻读。
  • READ_COMMITTED:阻止脏读,可导致不可重复读、幻读。
  • REPEATABLE_READ:阻止脏读和不可重复读,可导致幻读。
  • SERIALIZABLE:该级别下事务顺序执行,阻止上面的缺陷,开销很大。

X、后记

事务管理在现代应用中扮演着至关重要的角色,尤其是在分布式系统、微服务架构日益普及的今天,如何高效地管理数据一致性成为每个开发者都需要面对的挑战。Spring-Tx 模块以其简单、优雅且强大的特性,为事务管理提供了一站式的解决方案。

通过本篇文章的学习,相信您已经掌握了 Spring-Tx 的基本原理、配置方式以及编程式与声明式事务的具体用法。在实际项目中,选择合适的事务管理方式,合理配置事务属性,将显著提升系统的稳定性和可靠性。

期待您在今后的开发中,能够灵活运用 Spring-Tx 模块,为项目带来更高的效率和更好的性能。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Windows Docker笔记-安装docker

安装环境 操作系统&#xff1a;Windows 11 家庭中文版 docker版本&#xff1a;Docker Desktop version: 4.36.0 (175267) 注意&#xff1a; Docker Desktop 支持以下Windows操作系统&#xff1a; 支持的版本&#xff1a;Windows 10&#xff08;家庭版、专业版、企业版、教育…

Android学习20 -- 手搓App2(Gradle)

1 前言 昨天写了一个完全手搓的&#xff1a;Android学习19 -- 手搓App-CSDN博客 后面谷歌说不要用aapt&#xff0c;d8这些来搞。其实不想弄Gradle的&#xff0c;不过想着既然开始了&#xff0c;就多看一些。之前写过一篇Gradle&#xff0c;不过是最简单的编译&#xff0c;不涉…

[ Spring] Integrate Spring Boot Dubbo with Nacos 2025

文章目录 Dubbo Project StructureDeclare Plugins and RepositoriesIntroduce DependenciesDubbo Consumer PropertiesDubbo Provider ApplicationDubbo Provider ServiceDubbo Consumer PropertiesDubbo Consumer ApplicationDubbo Consumer ControllerCommand References Du…

团建 蓝桥杯省a 15

问题描述 小蓝正在和朋友们团建&#xff0c;有一个游戏项目需要两人合作&#xff0c;两个人分别拿到一棵大小为 nn 和 mm 的树&#xff0c;树上的每个结点上有一个正整数权值。 两个人需要从各自树的根结点 1 出发走向某个叶结点&#xff0c;从根到这个叶结点的路径上经过的所…

Ubuntu下Tkinter绑定数字小键盘上的回车键(PySide6类似)

设计了一个tkinter程序&#xff0c;在Win下绑定回车键&#xff0c;直接绑定"<Return>"就可以使用主键盘和小键盘的回车键直接“提交”&#xff0c;到了ubuntu下就不行了。经过搜索&#xff0c;发现ubuntu下主键盘和数字小键盘的回车键&#xff0c;名称不一样。…

单硬盘槽笔记本更换硬盘

背景 本人的笔记本电脑只有一个硬盘槽&#xff0c;而且没有M.2的硬盘盒&#xff0c;只有一个移动硬盘 旧硬盘&#xff1a;512G 新硬盘&#xff1a;1T 移动硬盘&#xff1a;512G 参考链接&#xff1a;https://www.bilibili.com/video/BV1iP41187SW/?spm_id_from333.1007.t…

matplotlib绘制三维曲面图时遇到的问题及解决方法

在科学计算和数据可视化中&#xff0c;三维曲面图是非常有用的工具&#xff0c;可以直观地展示数据的三维分布和关系。Matplotlib是Python中广泛使用的数据可视化库之一&#xff0c;提供了强大的三维绘图功能。然而&#xff0c;在实际使用过程中&#xff0c;用户可能会遇到各种…

vscode 如何通过Continue引入AI 助手deepseek

第一步&#xff1a; 在deepseek 官网上注册账号&#xff0c;得到APIKeys(deepseek官网地址) 创建属于自己的APIKey,然后复制这个key,(注意保存自己的key)! 第二步&#xff1a; 打开vscode,在插件市场安装Continue插件, 点击设置&#xff0c;添加deepseek模型&#xff0c;默认…

计算机网络——三种交换技术

目录 电路交换——用于电话网络 电路交换的优点&#xff1a; 电路交换的缺点&#xff1a; 报文交换——用于电报网络 报文交换的优点&#xff1a; 报文交换的缺点&#xff1a; 分组交换——用于现代计算机网络 分组交换的优点&#xff1a; 分组交换的缺点 电路交换——…

【Go语言快速上手】第一部分:Go 语言基础

文章目录 引言Go 语言的历史Go 语言的特点与优势学习 Go 语言的意义 1. Go 语言基础1.1 环境搭建下载和安装 Go 语言 SDK配置环境变量 (GOROOT, GOPATH)选择合适的 IDE 或编辑器 1.2 Go 语言基本语法变量声明与赋值变量作用域和生命周期 1.3 数据类型基本类型复合类型控制流if …

PostgreSQL函数自动Commit/Rollback所带来的问题

一、综述 今天在PostgreSQL遇到一个奇怪的现象&#xff0c;简而言之&#xff0c;是想用函数&#xff08;存储过程&#xff09;实现插入记录&#xff0c;整个过程没报错但事后却没找到记录&#xff01;忙活半天&#xff0c;才发现原因是PostgreSQL函数&#xff08;存储过程&…

linux 进程补充

环境变量 基本概念 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数 如&#xff1a;我们在编写C/C代码的时候&#xff0c;在链接的时候&#xff0c;从来不知道我们的所链接的动态静态库在哪 里&#xff0c;但是照样可以链接成功&#…

Spring Boot常用注解深度解析:从入门到精通

今天&#xff0c;这篇文章带你将深入理解Spring Boot中30常用注解&#xff0c;通过代码示例和关系图&#xff0c;帮助你彻底掌握Spring核心注解的使用场景和内在联系。 一、启动类与核心注解 1.1 SpringBootApplication 组合注解&#xff1a; SpringBootApplication Confi…

前部分知识复习05

一、多级渐远贴图MipMap 选择贴图&#xff0c;可以勾选贴图的多级渐远效果 [IntRange]_MipMap("MipMap",Range(0,12))0 //多级渐远贴图的LOD调节滑杆 _MipMapTexture("MipMapTexture",2D)"white"{} //定义多级渐远贴图 多级渐远贴图的采样…

解锁反序列化漏洞:从原理到防护的安全指南

目录 前言 一、什么是反序列化 二、反序列化漏洞原理 三、反序列化漏洞的危害 &#xff08;一&#xff09;任意代码执行 &#xff08;二&#xff09;权限提升 &#xff08;三&#xff09;数据泄露与篡改 四、常见的反序列化漏洞场景 &#xff08;一&#xff09;PHP 反…

理解 C 与 C++ 中的 const 常量与数组大小的关系

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C语言 文章目录 &#x1f4af;前言&#x1f4af;数组大小的常量要求&#x1f4af;C 语言中的数组大小要求&#x1f4af;C 中的数组大小要求&#x1f4af;为什么 C 中 const 变量可以作为数组大小&#x1f4af;进一步的…

MAC OS安装Homebrew

文章目录 1.下载Homebrew2.完成安装3.验证安装4.更新 Homebrew作为一个包管理器&#xff0c;提供了一种简便的方式来安装、更新和卸载各种命令行工具和应用程序。相比于手动下载和编译源代码&#xff0c;或者从不同的网站下载安装包&#xff0c;使用Homebrew可以显著减少这些操…

深入解析:如何利用 Python 爬虫获取商品 SKU 详细信息

在电商领域&#xff0c;SKU&#xff08;Stock Keeping Unit&#xff0c;库存单位&#xff09;详细信息是电商运营的核心数据之一。它不仅包含了商品的规格、价格、库存等关键信息&#xff0c;还直接影响到库存管理、价格策略和市场分析等多个方面。本文将详细介绍如何利用 Pyth…

OKHttp拦截器解析

OKHttp涉及到拦截器大概的执行步骤为&#xff1a; 1.通过newCall生成RealCall对象 具体代码如下&#xff1a; Override public Call newCall(Request request) {return new RealCall(this, request, false /* for web socket */);}2.调用Call的execute方法 当然这也可以是执…

深度学习系列--04.梯度下降以及其他优化器

目录 一.梯度概念 1.一元函数 2.二元函数 3.几何意义上的区别 二.梯度下降 1.原理 2.步骤 3.示例代码&#xff08;Python&#xff09; 4.不同类型的梯度下降 5.优缺点 三.动量优化器&#xff08;Momentum&#xff09; 适用场景 1.复杂地形的优化问题 2.数据具有噪声的问…