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;不涉…

团建 蓝桥杯省a 15

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

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

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

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

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

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可以显著减少这些操…

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

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

编程AI深度实战:给vim装上AI

系列文章&#xff1a; 编程AI深度实战&#xff1a;私有模型deep seek r1&#xff0c;必会ollama-CSDN博客 编程AI深度实战&#xff1a;自己的AI&#xff0c;必会LangChain-CSDN博客 编程AI深度实战&#xff1a;给vim装上AI-CSDN博客 编程AI深度实战&#xff1a;火的编程AI&…

2025年2月6日(anaconda cuda 学习 基本命令)

查看电脑的显卡型号是否支持CUDA的安装 https://developer.nvidia.com/zh-cn/cuda-gpus 查看可以安装的CUDA版本 https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html CUDA安装地址 https://developer.nvidia.com/cuda-toolkit-archive Anaconda下载地址 htt…

自动化构建——make/makefile

目录 背景使用推导过程如果多个文件呢&#xff1f;&#xff1f; 背景 会不会写makefile&#xff0c;从侧面可以说明一个人是否具有完成大型工程的能力makefile带来的好处就是——”自动化编译“&#xff0c;一旦写好&#xff0c;只需要一个make命令&#xff0c;整个工程完全自…

深度整理总结MySQL——SQL的执行顺序和流程

SQL的执行顺序和流程 SQL的执行顺序执行一条select语句,发生了什么呢连接器查询缓存解析SQL执行SQL预处理器优化器执行器 总结 SQL的执行顺序 这是一条标准的查询语句: 但实际上并不是从上到下去解析的,真实的执行顺序是: 我们先执行from,join来确定表之间的连接关系&#x…

R语言 | 使用 ComplexHeatmap 绘制热图,分区并给对角线分区加黑边框

目的&#xff1a;画热图&#xff0c;分区&#xff0c;给对角线分区添加黑色边框 建议直接看0和4。 0. 准备数据 # 安装并加载必要的包 #install.packages("ComplexHeatmap") # 如果尚未安装 library(ComplexHeatmap)# 使用 iris 数据集 #data(iris)# 选择数值列&a…

11 享元(Flyweight)模式

享元模式 1.1 分类 &#xff08;对象&#xff09;结构型 1.2 提出问题 做一个车管所系统&#xff0c;将会产生大量的车辆实体&#xff0c;如果每一个实例都保存自己的所有信息&#xff0c;将会需要大量内存&#xff0c;甚至导致程序崩溃。 1.3 解决方案 运用共享技术有效…

2025年Android NDK超全版本下载地址

Unity3D特效百例案例项目实战源码Android-Unity实战问题汇总游戏脚本-辅助自动化Android控件全解手册再战Android系列Scratch编程案例软考全系列Unity3D学习专栏蓝桥系列ChatGPT和AIGC &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分…