Spring 事务@Transactional

Spring 事务@Transactional

事务 @Transactional 可设置多个属性来控制事务的行为:

  • propagation:事务传播行为

  • isolation:隔离级别

  • timeout:超时设置(单位:秒)

  • readOnly:事务是否只读。如果设置为 true,Spring 会优化事务的执行,比如不会进行脏读。

  • rollbackFor:哪些异常会导致事务回滚。默认情况下,运行时异常会导致事务回滚,而检查型异常不会。

  • noRollbackFor:哪些异常不会导致事务回滚。

propagation 事务传播行为

事务传播行为 Propagation 定义了当一个事务方法被另一个事务方法调用时,事务应该如何传播。以下是 propagation 枚举的详细说明:

传播行为常量描述
当前存在事务,加入该事务REQUIRED如果当前存在事务,则加入该事务。如果当前没有事务,则创建一个新的事务(默认项)
当前存在事务,以非事务方式运行SUPPORTS如果当前存在事务,则加入该事务。如果当前没有事务,则以非事务的方式继续运行。
当前存在事务,必须在该事务中运行MANDATORY如果当前存在事务,则加入该事务。如果当前没有事务,则抛出异常。
创建一个新事务,挂起当前事务REQUIRES_NEW总是创建一个新的事务。如果当前存在事务,则将当前事务挂起。当自己执行完成后(提交或回滚),再接着执行被挂起的事务
以非事务方式运行,如果当前存在事务,则挂起NOT_SUPPORTED以非事务方式运行。如果当前存在事务,则挂起当前事务。
以非事务方式运行,如果当前存在事务,则抛出异常NEVER以非事务方式运行。如果当前存在事务,则抛出异常。
在嵌套事务中运行,如果当前没有事务,则创建NESTED如果当前存在事务,则在嵌套事务中运行。如果当前没有事务,则创建一个新的事务。

正确理解和使用事务传播行为对于确保事务的一致性和正确性至关重要。

isolation 隔离级别

隔离级别是事务管理的一个关键属性,它定义了一个事务在并发环境下如何与其他事务隔离。隔离级别决定了当前事务在并发环境下如何看到其他并发事务所做的修改。隔离级别越高,数据一致性越好,但并发性能可能会降低。反之,隔离级别越低,并发性能越好,但数据一致性风险增加;以下是 isolation 枚举的详细说明:

隔离级别常量描述
默认项DEFAULT默认,事务将使用底层数据库的默认隔离级别
读未提交READ_UNCOMMITTED最低级别的隔离,允许一个事务读取到其他事务尚未提交的数据,存在脏读(Dirty Read)问题,即读取到其他事务未提交的数据
读已提交READ_COMMITTED当前事务只能读取到其他事务已经提交的数据,解决了脏读问题,但仍然存在不可重复读(Non-Repeatable Read)问题,即在同一事务中多次读取同一数据集的结果可能不同
可重复读REPEATABLE_READ保证在同一个事务中多次读取同一数据集的结果是一致的,解决了不可重复读问题,但可能存在幻读(Phantom Read)问题,即一个事务在读取某个范围内的记录时,另一个事务插入或删除记录,导致第一个事务再次读取时返回不同的记录数
串行化SERIALIZABLE最高级别的隔离,通过锁定涉及的所有数据来确保事务序列化执行,从而避免了脏读、不可重复读和幻读,解决了所有并发问题,但性能成本最高,因为会显著降低并发性能

timeout 事务超时

限定事务在指定时间内完成。超时事务回滚。时间单位s。默认值-1,即事务将可以无限期地运行直到完成。

readOnly 事务是否只读

bool类型,默认 false,声明事务是否为只读事务,设置为 true 时,该事务只涉及读操作,不会进行修改数据库操作。对于只读事务,Spring 会进行一些优化,因为它知道该事务不更改数据,因此减少锁的持有时间,提高并发性能

只读事务常用于以下情况:

  • 查询操作:比如统计、数据导出等只涉及到查询数据库的操作。
  • 某些特定的更新操作:如果更新操作只涉及到更新一些不需要事务支持的字段(如:更新一些不需要保证原子性的字段),也可设置为只读。

当 readOnly 属性设置为 false(默认值)时,表示该事务可能会进行读和写操作。在这种情况下,Spring 不会应用只读事务的优化

rollbackFor 异常回滚

Exception 数组,默认{ RuntimeException.class };指定哪些异常类型会触发事务回滚。通过设置 rollbackFor 属性,可以扩展触发回滚的异常类型,包括已检查异常或其他异常类型

noRollbackFor 异常不回滚,继续执行

Exception 数组,无默认值,用于指定哪些异常类型不会触发事务回滚。通过设置 noRollbackFor 属性,可以排除某些异常类型,使得即使这些方法抛出这些异常,事务也不会回滚

在 Spring 中,默认情况下:

  • 当遇到 运行时异常(RuntimeException)或其子类时,Spring 事务管理器会触发事务回滚。
  • 当遇到 已检查异常(即非运行时异常,继承自 Exception 但不继承自 RuntimeException)时,Spring 事务管理器默认不会触发事务回滚

@Transactional 使用

  • 一个方法在类中调用另一个方法,并且被调用的方法没有自己的事务注解(如下所示),那么默认情况下,被调用方法中的数据库操作不会加入调用者方法的事务中,被调用方法中的数据库操作将在它们自己的独立事务中执行,调用者的事务不会自动传播到被调用者
      @Servicepublic class SaveService {@Transactionalpublic void funA() {this.funB();// 数据库操作this.funC();}public void funB() {// 数据库操作}public void funC() {// 数据库操作}}
    
  • 为了保持数据的一致性,建议被调用方法加上 @Transactional
  • 事务传播行为只适用于被 @Transactional 注解的方法
  • @Transactional 属性设置仅对当前所注解的方法起效,并不对方法内部调用的其他方法起效
    public class MyService {@Transactionalpublic void funA() {// 数据库操作(仅对这里的数据操作起效,并不对funB()起效)this.funB();}public void funB() {// 数据库操作}
    }
    
  • 对事务属性的设置也会影响事务的执行。
      // funA 方法被调用,它会在自己的事务中执行,且 funB 和 funC 方法会加入这个事务。// funC 或 funB 被单独调用,不会创建新事务,而是会在没有事务的上下文中执行@Servicepublic class MyService {@Transactionalpublic void funA() {this.funB();this.funC();}@Transactional(propagation = Propagation.SUPPORTS)public void funB() {// 数据库操作}@Transactional(propagation = Propagation.SUPPORTS)public void funC() {// 数据库操作}}
    
  • 事务传播行为由被调用方的方法决定,而不是调用方的方法
  • 嵌套事务(NESTED)需要数据库支持嵌套事务

    虽然 MySQL 不支持真正意义上的 嵌套事务,但使用Propagation.REQUIRES_NEW仍然是可行的,因为它会启动一个新的事务,并且这个新事务与外部事务是隔离的。如果新事务成功,它会被提交,即使外部事务最终失败也是如此。如果新事务失败,它会被回滚,并且不影响外部事务

  • 使用 REQUIRES_NEW 时,确保理解它会导致当前事务被挂起,并且新事务的异常不会导致当前事务回滚

拓展

@Transactional 仅能适用于单机数据库保持数据一致性,面对多节点多应用的分布式场景下,可使用Alibaba SETA框架实现分布式事务

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

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

相关文章

每日一题之二叉树

已知结点元素值为正整数且值不相同的一棵二叉树。 该二叉树通过给出其先序遍历序列和中序遍历序列构造而成。 输入一个整数x,针对此二叉树编写程序求出x的右子树中所有结点值的和(若x不在树上,输出-1)。 输入说明:第一…

win10系统使用Visual Studio 2019或cmake编译SDL2为32位库时出现error C2118: 负下标winnt.h的解决方法

提示: 下图蓝体字中的VS2008是错误的,其实SDL.sln是用VS2010版本的软件开发的(对于SDL-release-2.0.5.zip源码而言至少是这样,而2024-11-6为止SDL是2.30.9版本了,2.30.9版本则无需自己编译,只需下载带后缀…

推荐一款管道数据检索工具:Pipedata-Pro

Pipedata-Pro是一款专为设计石油、天然气、水和蒸汽管道及管道系统的工程师开发的应用程序。该应用程序提供了设计管道系统所需的工程数据,拥有一个全面的管道类型、配件和材料数据库。 软件特点: 1. 技术参数查询:Pipedata-Pro 提供关于管道…

算法竞赛(Python)-数组

文章目录 一 、排序算法二 、二分查找1 二分查找讲解2 二分查找题目(1)二分查找(2)在排序数组中查找元素的第一个和最后一个位置(3)两数之和 II - 输入有序数组 三、数组双指针1对撞指针对撞指针题目1&…

基于STM32的LCD1602显示Proteus仿真设计(仿真+程序+设计报告+讲解视频)

这里写目录标题 1.主要功能0. 资料清单&下载链接资料下载链接:2.仿真设计3. 程序设计4. 设计报告5. 框图 基于STM32的LCD1602显示Proteus仿真设计(仿真程序设计报告讲解视频) 仿真图proteus 8.9 程序编译器:keil 5 编程语言&#xff1a…

CPP贪心算法示例

设有n个正整数(n ≤ 20),将它们联接成一排,组成一个最大的多位整数。 例如:n3时,3个整数13,312,343联接成的最大整数为:34331213 又如:n4时,4个整…

SpringBoot项目编译报错 类文件具有错误的版本 61.0, 应为 52.0

springboot项目在编译时报错: /Users/Apple/Developer/art/caicai/cai-api/dubbo-samples/1-basic/dubbo-samples-spring-boot/dubbo-samples-spring-boot-provider/src/main/java/org/apache/dubbo/springboot/demo/provider/ProviderApplication.java:22:32 java…

写一个 EventBus 实现微信小程序的发布订阅,支持全局消息通知、跨页面通信,高效好用!

eventBus.js 在微信小程序中实现发布/订阅模式可以通过创建一个简单的事件管理器来实现。这个事件管理器将负责注册事件监听器、触发事件以及移除监听器。下面是一个具体的实现示例: 1. 创建事件管理器 首先,我们创建一个单独的文件 eventBus.js 来管理…

东胜物流软件 AttributeAdapter.aspx SQL 注入漏洞复现

0x01 产品简介 东胜物流软件是青岛东胜伟业软件有限公司一款集订单管理、仓库管理、运输管理等多种功能于一体的物流管理软件。该公司初创于2004年11月(前身为青岛景宏物流信息技术有限公司),专注于航运物流相关环节的产品和服务。东胜物流信息管理系统货代版采用MS-SQLser…

PVE纵览-备份与快照指南

PVE纵览-备份与快照指南 文章目录 PVE纵览-备份与快照指南摘要1 备份与快照概述定义与区别备份与快照在PVE中的应用场景 2 PVE 备份功能详解备份类型与策略配置备份任务自动化备份管理 3 PVE 快照功能详解快照的工作原理快照的创建与恢复机制快照对系统性能的影响快照的使用场景…

Mac如何实现最简单的随时监测实时运行状态的方法

Mac book有着不同于Windows的设计逻辑与交互设计,使得Mac book有着非常棒的使用体验,但是在Mac电脑的使用时间过长时,电脑也会出现响应速度变慢或应用程序崩溃的情况,当发生的时候却不知道什么原因导致的,想要查询电脑…

JavaWeb合集23-文件上传

二十三 、 文件上传 实现效果&#xff1a;用户点击上传按钮、选择上传的头像&#xff0c;确定自动上传&#xff0c;将上传的文件保存到指定的目录中&#xff0c;并重新命名&#xff0c;生成访问链接&#xff0c;返回给前端进行回显。 1、前端实现 vue3AntDesignVue实现 <tem…

Leetcode 34 Find First and Last Position of Element in Sorted Array

题意&#xff1a;找到非严格递增的数组中和target相等的左右边界 https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array/description/ 解答&#xff1a; 经典二分&#xff0c;找左右边界&#xff0c;要查看l是否满足题意 class Solution …

LinkedList和单双链表。

java中提供了双向链表的动态数据结构 --- LinkedList&#xff0c;它同时也实现了List接口&#xff0c;可以当作普通的列表来使用。也可以自定义实现链表。 单向链表&#xff1a;一个节点本节点数据下个节点地址 给定两个有序链表的头指针head1和head2&#xff0c;打印两个链表…

实现简易开屏弹窗

要实现一个简易的开屏弹窗&#xff0c;并展示一些文章内容&#xff0c;以下是一个简单的HTML和CSS实现。这个弹窗会在页面加载时显示&#xff0c;并包含一个标题和一些文章内容。用户可以点击按钮关闭弹窗&#xff0c;关闭后&#xff0c;弹窗的状态会保存在浏览器的 sessionSto…

WPF之iconfont(字体图标)使用

1&#xff0c;前文&#xff1a; WPF的Xaml是与前端的Html有着高度相似性的标记语言&#xff0c;所以Xaml也可同Html一般轻松使用阿里提供的海量字体图标&#xff0c;从而有效的减少开发工作度。 2&#xff0c;下载字体图标&#xff1a; 登录阿里图标库网iconfont-阿里巴巴矢量…

图神经网络(GNN)入门笔记(2)——从谱域理解图卷积,ChebNet和GCN实现

一、谱域图卷积&#xff08;Spectral Domain Graph Convolution&#xff09; 与谱域图卷积&#xff08;Spectral Domain Graph Convolution&#xff09;对应的是空间域&#xff08;Spatial Domain&#xff09;图卷积。本节学习的谱域图卷积指的是通过频率来理解卷积的方法。 …

leetcode92:反转链表||

给你单链表的头指针 head 和两个整数 left 和 right &#xff0c;其中 left < right 。请你反转从位置 left 到位置 right 的链表节点&#xff0c;返回 反转后的链表 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], left 2, right 4 输出&#xff1a;[1,4,3,2…

知识图谱是如何通过数据集构建的,比如通过在MSCOCO和Flickr30k数据集和Visual Genome数据集

系列博客目录 文章目录 系列博客目录1. 数据准备与实体识别2. 关系抽取3. 图结构构建4. 图嵌入学习5. 知识图谱存储与查询示例&#xff1a;通过 Visual Genome 构建一个简单的知识图谱 构建知识图谱通常涉及从数据集中提取实体和关系&#xff0c;并将其结构化为图的形式。在 MS…

Python-安装与PyCharm的安装配置(1)

目录 安装 打开运行 PyCharm的安装 新建项目 安装 找到官网下载对应的电脑对应的版本 Welcome to Python.org -- 官网 下载稳定版的 安装记得勾选配置环境&#xff0c;这样自己就不需要再配置环境了 安装成功 至此python的运行环境就安装好了 打开运行 在开始菜单中可以…