当前位置: 首页 > 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…...

剑指offer20_链表中环的入口节点

链表中环的入口节点 给定一个链表&#xff0c;若其中包含环&#xff0c;则输出环的入口节点。 若其中不包含环&#xff0c;则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

Python爬虫(一):爬虫伪装

一、网站防爬机制概述 在当今互联网环境中&#xff0c;具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类&#xff1a; 身份验证机制&#xff1a;直接将未经授权的爬虫阻挡在外反爬技术体系&#xff1a;通过各种技术手段增加爬虫获取数据的难度…...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

laravel8+vue3.0+element-plus搭建方法

创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题

分区配置 (ptab.json) img 属性介绍&#xff1a; img 属性指定分区存放的 image 名称&#xff0c;指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件&#xff0c;则以 proj_name:binary_name 格式指定文件名&#xff0c; proj_name 为工程 名&…...

C语言中提供的第三方库之哈希表实现

一. 简介 前面一篇文章简单学习了C语言中第三方库&#xff08;uthash库&#xff09;提供对哈希表的操作&#xff0c;文章如下&#xff1a; C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...

tomcat指定使用的jdk版本

说明 有时候需要对tomcat配置指定的jdk版本号&#xff0c;此时&#xff0c;我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...