当前位置: 首页 > news >正文

探究Spring事务:了解失效场景及应对策略

在现代软件开发中,数据的一致性和完整性是至关重要的。为了保证这些特性,Spring框架提供了强大的事务管理机制,让开发者能够更加自信地处理数据库操作。然而,事务并非银弹,存在一些失效的情景,本文将带您深入探究Spring事务及其失效场景,并为您呈现应对策略。

spring事务失效的场景

_20230804232601.png

@Transactional概述

在Spring Boot中,@Transactional是一个用于声明式事务管理的注解。事务是一种用来维护数据库操作的一致性和隔离性的机制,确保在一组操作中,要么所有操作都成功提交,要么所有操作都回滚,以保持数据的完整性。@Transactional注解让你能够在方法级别上定义事务的行为,而无需显式编写事务管理代码。

@Transactional注解的详细解释:

  • 标记事务起点:@Transactional注解放在方法上,表示该方法应该在一个事务内执行。当方法被调用时,Spring会自动开始一个事务。

  • 事务属性: @Transactional注解支持多个属性,用于配置事务的各个方面。一些常用的属性包括:

    • isolation:指定事务的隔离级别,定义了事务之间的可见性。例如,Isolation.READ_COMMITTED表示读已提交的隔离级别。
    • propagation:定义了事务的传播行为,即方法被另一个事务方法调用时如何处理事务。例如,Propagation.REQUIRED表示如果已存在事务,则沿用该事务,否则创建一个新的事务。
    • readOnly:指定事务是否只读。如果只读,可以优化事务处理,因为不需要考虑写操作。
    • timeout:定义事务的超时时间,超过该时间未提交则自动回滚。
    • rollbackFornoRollbackFor:指定在哪些异常情况下回滚事务或不回滚事务。
  • 嵌套事务: 如果在方法中调用了另一个被@Transactional注解标记的方法,那么默认情况下会共享外部方法的事务。如果希望内部方法有自己的事务,可以使用Propagation.REQUIRES_NEW传播行为。

  • 回滚策略: 默认情况下,Spring会将未捕获的运行时异常(RuntimeException及其子类)作为触发事务回滚的标志。你也可以通过rollbackFor属性指定哪些异常触发回滚。

  • 应用范围: @Transactional注解可以用于类级别(作用于所有方法)或方法级别(作用于单个方法),具体取决于你的需求。

  • 生效方式: @Transactional注解依赖于Spring的AOP(面向切面编程)技术,它会在运行时通过代理机制来拦截方法调用,并根据注解的配置来管理事务。

TransactionSynchronizationManager辅助打印事务

在Spring Boot中,你可以使用TransactionSynchronizationManager来获取有关已开启事务的信息。TransactionSynchronizationManager是Spring的一个工具类,用于管理和监视事务的状态。要打印已开启的事务,你可以通过以下步骤进行:

  • 导入必要的类: 首先,确保你的类中导入了TransactionSynchronizationManager类。
import org.springframework.transaction.support.TransactionSynchronizationManager;
  • 打印当前事务名称或者状态
boolean isTransactionActive = TransactionSynchronizationManager.isActualTransactionActive();if (isTransactionActive) {System.out.println("An active transaction is present.");System.out.println(TransactionSynchronizationManager.getCurrentTransactionName());
} else {System.out.println("No active transaction.");
}

失效场景详解

  • 未被Spring管理的对象

未被标记为@Component、@Service、@Repository或其他Spring管理注解的普通Java类不会被Spring自动管理。

import org.springframework.transaction.annotation.Transactional;public class NoManageService {
/**
import org.springframework.transaction.annotation.Transactional;public class NoManageService {/*** 事务不生效场景:未被Spring管理的对象*/@Transactionalpublic void doHandle() {// 一通处理}
}}
  • 异常未被正确捕获和抛出

异常被捕获但未重新抛出,事务将不会回滚。

    /*** 事务不生效场景:异常未被正确捕获和抛出*/@Transactional(rollbackFor = Exception.class)public void method1(){try {//一通处理猛如虎}catch (Exception e){//异常只吞不吐不回滚}}
  • 在非公共方法上使用@Transactional
    /*** 事务不生效场景:在非公共方法上使用@Transactional*/@Transactional(rollbackFor = Exception.class)private void method2(){//一通处理猛如虎}
  • 事务方法内部调用

当事务方法内部通过普通的方法调用,而不是通过Spring管理的Bean调用其他带有@Transactional注解的方法时,事务可能失效。这是因为Spring的事务机制是基于代理实现的,只有通过代理对象调用的方法才能被AOP拦截并应用事务。

    /*** 事务不生效场景:事务方法内部调用,未被AOP拦截*/public void method3(){method5();}@Resourceprivate TestService testService;/*** 事务生效,使用自我引用的方式调用: 如果在同一个类中需要在事务内部调用其他事务方法,* 可以通过自我引用的方式来调用,以便事务代理可以生效。*/public void method4(){testService.method5();}@Transactional(rollbackFor = Exception.class)public void method5(){//一通处理猛如虎}
  • 事务传播机制配置错误

如果在方法中调用了另一个被@Transactional注解标记的方法,那么默认情况下会共享外部方法的事务。如果希望内部方法有自己的事务,可以使用Propagation.REQUIRES_NEW传播行为。

    /*** method6中调用method7,会共享method6方法的事务*/@Transactional(rollbackFor = Exception.class)public void method6(){//获取当前事务名称,若未开启事务,则为nullString  tranName = TransactionSynchronizationManager.getCurrentTransactionName();log.info("method6事务名称=======》{}",tranName);//一通处理猛如虎testService.method7();}@Transactional(rollbackFor = Exception.class)public void method7(){//获取当前事务名称,若未开启事务,则为nullString  tranName = TransactionSynchronizationManager.getCurrentTransactionName();log.info("method7事务名称=======》{}",tranName);//一通处理猛如虎}

调用method6则会打印

23:04:48.861 [http-nio-8180-exec-1] INFO  c.x.t.TestServiceImpl - [method6,69] - method6事务名称=======》cn.xj.transactional.TestServiceImpl.method6
23:04:48.862 [http-nio-8180-exec-1] INFO  c.x.t.TestServiceImpl - [method7,77] - method7事务名称=======》cn.xj.transactional.TestServiceImpl.method6
    /*** method8中调用method9,method9会重新开启个事务*/@Transactional(rollbackFor = Exception.class)public void method8(){//获取当前事务名称,若未开启事务,则为nullString  tranName = TransactionSynchronizationManager.getCurrentTransactionName();log.info("method8事务名称=======》{}",tranName);//一通处理猛如虎testService.method9();}@Transactional(rollbackFor = Exception.class,propagation= Propagation.REQUIRES_NEW)public void method9(){//获取当前事务名称,若未开启事务,则为nullString  tranName = TransactionSynchronizationManager.getCurrentTransactionName();log.info("method9事务名称=======》{}",tranName);//一通处理猛如虎}

调用method8则会打印

23:12:51.058 [http-nio-8180-exec-1] INFO  c.x.t.TestServiceImpl - [method8,93] - method8事务名称=======》cn.xj.transactional.TestServiceImpl.method8
23:12:51.086 [http-nio-8180-exec-1] INFO  c.x.t.TestServiceImpl - [method9,101] - method9事务名称=======》cn.xj.transactional.TestServiceImpl.method9

总结

Spring事务为我们提供了一个强大的工具来维护数据的一致性和完整性。然而,在使用过程中,了解事务失效的场景以及应对策略同样重要。通过合理配置事务传播行为、异常处理以及使用注解管理事务,我们能够更好地应对各种情况,确保系统的稳定性和可靠性。

相关文章:

探究Spring事务:了解失效场景及应对策略

在现代软件开发中,数据的一致性和完整性是至关重要的。为了保证这些特性,Spring框架提供了强大的事务管理机制,让开发者能够更加自信地处理数据库操作。然而,事务并非银弹,存在一些失效的情景,本文将带您深…...

Maven Manifold 条件编译

Maven 配置 通过 Maven 的不同 profile 实现不同环境传递不同符号。另外 lombok 可以 manifold 一同使用&#xff0c;见下方配置。 <properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.targ…...

4.数组与基本数学函数

一、数组 1.概念 数组是存放相同类型对象的容器&#xff0c;数组中存放的对象没有名字&#xff0c;而是要通过其所在的位置访问。数组中的每一个元素都相当于一个普通的变量&#xff0c;可以和普通变量一样进行赋值操作。 数组可以帮助我们批量地处理相同数据类型的相关数据…...

python与深度学习(十六):CNN和宝可梦模型二

目录 1. 说明2. 宝可梦模型的CNN模型测试2.1 导入相关库2.2 加载模型2.3 设置保存图片的路径2.4 加载图片2.5 数据处理和归一化2.6 对图片进行预测2.7 显示图片 3. 完整代码和显示结果4. 多张图片进行测试的完整代码以及结果 1. 说明 本篇文章是对上篇文章宝可梦模型训练的模型…...

PTA 1030 Travel Plan

个人学习记录&#xff0c;代码难免不尽人意。 A traveler’s map gives the distances between cities along the highways, together with the cost of each highway. Now you are supposed to write a program to help a traveler to decide the shortest path between his/h…...

MFC、Qt、WPF?该用哪个?

MFC、Qt和WPF都是流行的框架和工具&#xff0c;用于开发图形用户界面&#xff08;GUI&#xff09;应用程序。选择哪个框架取决于你的具体需求和偏好。MFC&#xff08;Microsoft Foundation Class&#xff09;是微软提供的框架&#xff0c;使用C编写&#xff0c;主要用于Windows…...

使用logback记录日志

1. Pom引用依赖 <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.11</version> </dependency> 2. logback.xml <?xml version"1.0" encoding"U…...

企业工程项目管理系统源码(三控:进度组织、质量安全、预算资金成本、二平台:招采、设计管理) em

​ 工程项目管理软件&#xff08;工程项目管理系统&#xff09;对建设工程项目管理组织建设、项目策划决策、规划设计、施工建设到竣工交付、总结评估、运维运营&#xff0c;全过程、全方位的对项目进行综合管理 工程项目各模块及其功能点清单 一、系统管理 1、数据字典&#…...

【安装】XMind2022XMind2020安装教程(资源)

Xmind是一个制作思维导图很便利的软件。 1.资源链接 Xmind2022: 链接&#xff1a;https://pan.baidu.com/s/1j4DFedxxX2YJ3HBy1-MpHw?pwdxmin 提取码&#xff1a;xmin Xmind2020: 链接&#xff1a;https://pan.baidu.com/s/1wNqMApuy0yoBF2CvpBDpDA?pwdxmin 提取码&#x…...

Windows下QT Creator安装MinGW 32bit编译器

前言 注&#xff1a;本作者是基于FFmpeg开发需要&#xff0c;故在Windows下QT Creator中安装MinGW 32bit编译器&#xff01;其它型号编译器参照此文章基本可以实现&#xff01; 一、下载需要的编译器 1、下载链接 链接&#xff1a; 链接&#xff1a;https://pan.baidu.com/…...

Emacs之解决键值绑定冲突问题(一百二十三)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…...

瞄准产业应用,大模型加持的深兰科技AI虚拟数字人落地业务场景

伴随ChatGPT的问世&#xff0c;在技术与商业运作上都日渐发展成熟的AI数字人产业正持续升温。 目前的AI数字人不仅拥有超高“颜值”&#xff0c;同时还拥有更为丰富的、细腻的表情和动作。更有甚者&#xff0c;AI数字人已经具备自定义构建知识图谱、自主对话、不断学习成长的能…...

【网络基础进阶之路】基于MGRE多点协议的实战详解

PS&#xff1a;本要求基于华为的eNSP模拟软件进行 具体要求&#xff1a; 完成步骤&#xff1a; 1、根据上述要求&#xff0c;对各路由器进行地址安排&#xff0c;如下图。 2、进入各路由器&#xff0c;对每个端口进行地址设置。 R1路由器设置&#xff1a; ISP路由器设置&…...

Spark、RDD、Hive 、Hadoop-Hive 和传统关系型数据库区别

Hive Hadoop Hive 和传统关系型数据库区别 Spark 概念 基于内存的分布式计算框架 只负责算 不负责存 spark 在离线计算 功能上 类似于mapreduce的作用 MapReduce的缺点 运行速度慢 &#xff08;没有充分利用内存&#xff09;接口比较简单&#xff0c;仅支持Map Reduce功能…...

[运维]python 启用http 文件服务

要在Python中启用HTTP文件服务&#xff0c;您可以使用内置的http.server模块&#xff08;在Python 3中&#xff09;或SimpleHTTPServer模块&#xff08;在Python 2中&#xff09;。 在Python 3中&#xff1a; python -m http.server在Python 2中&#xff1a; python -m Simp…...

electron-builder 打包 exe 异常错误集锦

项目技术 vue-electron vue-router vuex vuex-electron element-ui echarts mysql 打包异常 Error: Unresolved node modules: vue Error: Unresolved node modules: vue at D:\Code\Demo\Vue\Voice\App\node_modules\_app-builder-lib20.44.4app-builder-lib\src\…...

14-5_Qt 5.9 C++开发指南_基于HTTP 协议的网络应用程序

文章目录 1. 实现高层网络操作的类2. 基于HTTP协议的网络文件下载3.源码3.1 可是化UI设计3.2 mainwindow.h3.3 mainwindow.cpp 1. 实现高层网络操作的类 Qt 网络模块提供一些类实现 OSI 7 层网络模型中高层的网络协议&#xff0c;如 HTTP、FTP、SNMP等&#xff0c;这些类主要是…...

Kotlin委托

委托 委托 代理 方法内的成员永远拿不到thisRef&#xff1a;官方委托和自定义委托-》方法里面没办法使用反射 委托只能类委托和属性委托 Kotlin委托 本文链接&#xff1a;https://blog.csdn.net/feather_wch/article/details/132095759 类委托 1、类委托 委托的是接口的方…...

分布式协议与算法——CAP理论、ACID理论、BASE理论

CAP理论 CAP理论&#xff0c;对分布式系统的特性做了高度抽象&#xff0c;比如抽象成了一致性、可用性和分区容错性&#xff0c;并对特性间的冲突&#xff08;也就是CAP不可能三角&#xff09;做了总结。 CAP三指标 CAP理论对分布式系统的特性做了高度抽象&#xff0c;形成了…...

接口测试 Jmeter 接口测试 —— 请求 Headers 与传参方式

一、 背景&#xff1a; 在使用 Jmeter 进行接口测试时&#xff0c;有些小伙伴不知道 Headers 和请求参数 (Parameters&#xff0c;Body Data) 的联系&#xff0c;本文主要讲 Content-Type 为 application/x-www-form-urlencoded 和 application/json 的场景。 1、使用 Parame…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时&#xff0c;你可能需要保留重要的数据&#xff0c;例如通讯录。好在&#xff0c;将通讯录从 iPhone 转移到 Android 手机非常简单&#xff0c;你可以从本文中学习 6 种可靠的方法&#xff0c;确保随时保持连接&#xff0c;不错过任何信息。 第 1…...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度…...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;使用DevEco Studio作为开发工具&#xff0c;采用Java语言实现&#xff0c;包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

云原生玩法三问:构建自定义开发环境

云原生玩法三问&#xff1a;构建自定义开发环境 引言 临时运维一个古董项目&#xff0c;无文档&#xff0c;无环境&#xff0c;无交接人&#xff0c;俗称三无。 运行设备的环境老&#xff0c;本地环境版本高&#xff0c;ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...

算法:模拟

1.替换所有的问号 1576. 替换所有的问号 - 力扣&#xff08;LeetCode&#xff09; ​遍历字符串​&#xff1a;通过外层循环逐一检查每个字符。​遇到 ? 时处理​&#xff1a; 内层循环遍历小写字母&#xff08;a 到 z&#xff09;。对每个字母检查是否满足&#xff1a; ​与…...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...

Unity UGUI Button事件流程

场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...

毫米波雷达基础理论(3D+4D)

3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文&#xff1a; 一文入门汽车毫米波雷达基本原理 &#xff1a;https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...

轻量级Docker管理工具Docker Switchboard

简介 什么是 Docker Switchboard &#xff1f; Docker Switchboard 是一个轻量级的 Web 应用程序&#xff0c;用于管理 Docker 容器。它提供了一个干净、用户友好的界面来启动、停止和监控主机上运行的容器&#xff0c;使其成为本地开发、家庭实验室或小型服务器设置的理想选择…...

从零手写Java版本的LSM Tree (一):LSM Tree 概述

&#x1f525; 推荐一个高质量的Java LSM Tree开源项目&#xff01; https://github.com/brianxiadong/java-lsm-tree java-lsm-tree 是一个从零实现的Log-Structured Merge Tree&#xff0c;专为高并发写入场景设计。 核心亮点&#xff1a; ⚡ 极致性能&#xff1a;写入速度超…...