Spring5应用之事务属性

news2024/11/19 22:38:27

作者简介:☕️大家好,我是Aomsir,一个爱折腾的开发者!
个人主页:Aomsir_Spring5应用专栏,Netty应用专栏,RPC应用专栏-CSDN博客
当前专栏:Spring5应用专栏_Aomsir的博客-CSDN博客

文章目录

  • 参考文献
  • 前言
  • 事务属性
    • 什么是事物属性?
    • 如何添加事务属性?
  • 隔离属性
    • 脏读
      • 解决方案
    • 不可重复读
      • 解决方案
    • 幻影读
      • 解决方案
    • 注意事项
  • 传播属性
    • 解决方案
  • 只读属性
  • 超时属性
  • 异常属性
  • 总结

参考文献

  • 孙哥suns说Spring5~学不会Spring? 因为你没找对人~孙帅
  • Spring官方文档

前言

在前两篇文章中,我们深入探索了Spring与MyBatis的整合技术,并详细讨论了Spring在事务处理方面的能力。今天,我决定进一步深入研究Spring,在事务属性上进一步的深入研究

事务属性

什么是事物属性?

事务属性是用来描述事务特性的一组值。主要包括隔离属性传播属性只读属性超时属性异常属性。通过这些属性,我们可以全面地描述和管理事务的行为

如何添加事务属性?

在上一篇文章中,我们已经探讨了如何在原始方法的类或方法上使用@Transaction注解来定义事务的切入点。要设置事务属性,我们只需在这一注解中配置相应的属性值。例如,isolation用于指定隔离级别propagation表示传播行为readOnly标识该事务是否为只读rollbackFor定义哪些异常会触发事务回滚,而timeOut指定事务的超时时间。接下来,我们会详细解析每一个属性的具体值和含义,以帮助大家更深入地理解和使用事务属性

隔离属性

隔离属性主要描述了事务如何解决数据库事务并发操作中的问题。在此之前,我们首先要明确什么是并发,以及并发中可能会遇到哪些问题,以及如何解决这些问题。

什么是并发? 并发是指多个事务在同一时刻,对相同的数据进行访问和操作。

并发会产生哪些问题? 并发操作中可能出现的问题包括脏读不可重复读幻影读

并发问题如何解决? 并发中的问题可以通过设定合适的隔离属性来解决。根据隔离属性的不同值,我们可以有效地避免或解决在并发处理过程中出现的这些问题

脏读

所谓脏读,是指一个事务读取到了另一个事务尚未提交的数据,这种操作可能导致当前事务中的数据不一致。想象一个场景:如果事务的隔离级别设置得不够高,它可能会读取到另一事务已修改但尚未提交的数据。如果在此基础上,我们对这份数据进行了进一步的修改、添加或删除,而后来那个外部事务决定回滚,那么当前事务所做的所有操作都可能变得无效或导致数据错误

解决方案

为了避免脏读,可以将事务的隔离属性设置为“读已提交”。这样,事务只能读取其他事务已经提交的数据,从而确保数据的一致性。在代码中,这可以通过以下注解属性来实现:

@Transaction(isolation=Isolation.READ_COMMITTED)

不可重复读

所谓不可重复读,是指在同一个事务内多次读取相同数据时,得到的结果不同。举个例子,假设在事务A中,第一次查询某数据得到的结果是1000。而在事务A的两次查询之间,另外一个事务B将这个数据减少了200。当事务A再次查询时,得到的结果就变成了800,从而导致事务A中出现了数据不一致的情况

解决方案

为了避免不可重复读的问题,我们可以将事务的隔离属性设置为“可重复读”。这样的设置确保在事务执行过程中,对同一数据的多次读取都能获得一致的结果。在代码中,可以通过以下注解属性来实现:

其本质是为相关数据加上行锁,确保在当前事务执行期间,其他事务不能修改这部分数据

@Transaction(isolation=Isolation.REPEATABLE_READ)

幻影读

所谓幻影读,是指在同一个事务中对整张表进行多次统计查询时,得到的结果各不相同,从而在事务内产生数据不一致的问题

解决方案

为了避免幻影读的问题,我们可以将事务的隔离属性设置为“串行化”(SERIALIZABLE)。这样的设置可以确保在事务执行过程中,对整张表的多次统计查询都能获得一致的结果。在代码中,可以通过以下注解来实现:

其核心机制是为整张表加上表锁,确保在当前事务执行期间,其他事务不能对此表进行添加或删除操作。

@Transaction(isolation=Isolation.SERIALIZABLE)

注意事项

  1. 数据库默认隔离级别: Spring提供的事务属性默认值会根据不同类型的数据库的默认隔离级别进行动态选择。
  2. 灵活选择隔离属性: 在实际应用中,我们应当灵活地选择隔离属性。根据具体的业务需求,选择合适的隔离属性,当然,默认的设置通常也是推荐的。
  3. 解决并发问题: 在实战中遇到并发问题时,常用的解决方法是采用悲观锁。例如,可以使用JPA的Version或者通过MyBatis的拦截器进行自定义开发

传播属性

传播属性主要描述了如何解决事务嵌套的问题。事务嵌套发生在一个主事务中包含多个子事务的情况。

例如,当AService中的a方法启动一个事务时,这个a方法可能会调用BService的b方法和CService的c方法,这两个方法都各自拥有独立的事务,这种情况下就构成了事务嵌套。这样的嵌套可能导致各个子事务之间相互影响,进而使主事务失去其原子性。

通过正确地设置传播属性,我们可以确保在整个操作过程中只存在一个统一的事务。

解决方案

当我们需要设定事务的传播行为,可以在事务注解中添加propagation属性。各个传播属性的具体值及其含义可以参考下表。

在实际开发中,REQUIREDSUPPORTS这两个传播属性可以解决99%的场景需求

默认的传播属性是REQUIRED,因此对于增、删、改的方法,我们通常不需要手动设置。而对于查询方法,我们则需要手动将其传播属性设置为SUPPORTS
在这里插入图片描述

只读属性

对于仅涉及查询操作的业务方法,我们可以添加只读属性,从而优化运行效率。这可以通过readOnly属性来实现。虽然它的默认值是false,但在需要的时候,我们可以手动开启它,使查询操作更加高效

超时属性

超时属性定义了事务执行的最长允许时间。这在某些场景下尤为关键,例如,当当前事务所需的数据被另一个事务或代码锁定时,本事务可能需要等待并尝试加锁。 我们可以通过timeout属性来设置超时限制,其单位为秒。设定超时属性后,为了验证其效果,我们可以在业务方法中插入线程休眠代码来进行模拟和测试

异常属性

异常属性指定了在事务中发生何种异常时应执行回滚操作,以及在哪些异常下应提交数据。我们可以通过属性rollbackFornoRollbackFor来进行设置。

在Spring的事务管理中,异常属性的默认设置是

  • 当事务中发生RuntimeException及其子类的异常时,系统会自动进行回滚
  • 当事务中发生Exception及其子类的异常时,则默认执行提交操作。

对于大多数实际场景,建议沿用此默认值,尤其是对于RuntimeException及其子类

总结

经过上述详细的探讨,我们对Spring事务中的各项属性有了深入的了解。现在,我们来做一个简明扼要的总结:

  1. 隔离属性:推荐使用默认值。
  2. 传播属性:对于增删改操作,建议直接使用默认值,即REQUIRED。而对于查询操作,应手动设置为SUPPORTS。
  3. 只读属性:对于增删改操作,使用默认值,即false;对于查询操作,应手动设置为true。
  4. 超时属性:根据具体业务需求来决定,但默认值为-1。
  5. 异常属性:建议使用默认设
    因此,总结如下:
  • 对于增删改操作:@Transaction
  • 对于查询操作:@Transaction(propagation=Propagation.SUPPORTS, readOnly=true)

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

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

相关文章

指针拔尖(2)(巩固提高,全网最牛,包会,看不懂带电脑来找我)

文章目录 前言变量的声明 一、函数指针二、函数指针数组三、指向函数指针数组的指针四、 回调函数总结 前言 提示:本章是指针拔尖系列的终章,有四大知识点。 一、函数指针 二、函数指针数组 三、指向函数指针数组的指针 四、回调函数 但学习这些知识点我…

【STM32单片机】防盗报警器设计

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用STM32F103C8T6单片机控制器,使用按键、动态数码管、蜂鸣器、指示灯、热释电人体红外传感器等。 主要功能: 系统运行后,默认处于布防状态,D1指示灯…

Netty深入浅出Java网络编程学习笔记(三) 优化篇

目录 五、优化 1、拓展序列化算法 序列化接口 枚举实现类 修改原编解码器 2、参数调优 CONNECT_TIMEOUT_MILLIS 使用 源码分析 SO_BACKLOG 三次握手与连接队列 作用 默认值 TCP_NODELAY SO_SNDBUF & SO_RCVBUF ALLOCATOR 使用 ByteBufAllocator类型 RCVBUF_ALLOCATOR 3、RP…

2023.10.11

#include <iostream>using namespace std;class Sofa{ private:int price;int* size; public://无参构造Sofa(){}//有参构造Sofa(int p,int size):price(p),size(new int(size)){}//析构~Sofa(){delete size;}//拷贝构造Sofa(Sofa &other):price(other.price),size(n…

TensorFlow入门(二十、损失函数)

损失函数 损失函数用真实值与预测值的距离指导模型的收敛方向,是网络学习质量的关键。不管是什么样的网络结构,如果使用的损失函数不正确,最终训练出的模型一定是不正确的。常见的两类损失函数为:①均值平方差②交叉熵 均值平方差 均值平方差(Mean Squared Error,MSE),也称&qu…

[计算机网络基础]物理层详解

首先说明,基本的概述我还没写完,那部分虽然简单但是感觉要照顾到很多概念..... 以及本系列博客使用点模型并非iso模型,也并非tcp/IP模型,而是我们俗称的教学模型 也就是:物理层,数据链路层,网络层,传输层,应用层这五个,整个模型大多数是在教学中使用的,现实中基本不会这样子划…

spring容器ioc和di

spring ioc 容器的创建 BeanFactory 接口提供了一种高级配置机制&#xff0c;能够管理任何类型的对象&#xff0c;它是SpringIoC容器标准化超接口&#xff01; ApplicationContext 是 BeanFactory 的子接口。它扩展了以下功能&#xff1a; 更容易与 Spring 的 AOP 功能集成消…

K8S云计算系列-(3)

K8S Kubeadm案例实战 Kubeadm 是一个K8S部署工具&#xff0c;它提供了kubeadm init 以及 kubeadm join 这两个命令来快速创建kubernetes集群。 Kubeadm 通过执行必要的操作来启动和运行一个最小可用的集群。它故意被设计为只关心启动集群&#xff0c;而不是之前的节点准备工作…

echarts仪表盘vue

<div class"ybptx" ref"btryzb"></div>mounted() {this.getBtData();},getBtData() {var chart this.$echarts.init(this.$refs.btryzb);var data_czzf 88;var option {series: [{name: 内层数据刻度,type: gauge,radius: 80%,min: 0,max: 1…

Selenium+Pytest自动化测试框架

前言 selenium自动化 pytest测试框架 本章你需要 一定的python基础——至少明白类与对象&#xff0c;封装继承 一定的selenium基础——本篇不讲selenium&#xff0c;不会的可以自己去看selenium中文翻译网 测试框架简介 测试框架有什么优点呢&#xff1a; 代码复用率高&…

【安全】linux audit审计使用入门

文章目录 1 audit简介2 auditctl的使用2 audit配置和规则3 工作原理4 audit接口调用4.1 获取和修改配置4.2 获取和修改规则4.3 获取审计日志 5 audit存在的问题5.1 内核版本5.2 审计日志过多造成的缓存队列和磁盘问题5.2 容器环境下同一个命令的日志存在差异 6 参考文档 1 audi…

【gmail注册教程】手把手教你注册Google邮箱账号

手把手教你注册Google邮箱账号 写在前面&#xff1a; 要注意&#xff0c;注册Google邮箱必须要确保自己能够 科学上网&#xff0c;如果暂时做不到&#xff0c;请先进行相关学习。使用的手机号是大陆&#xff08;86&#xff09;的。 在保证自己能够科学上网后&#xff0c;在浏…

[硬件基础]-双稳态多谐振荡器配置

双稳态多谐振荡器配置 文章目录 双稳态多谐振荡器配置1、概述2、双稳态多谐振荡器的内部运行原理 在上一篇文章中&#xff0c;我们深入了解了555定时器在单稳态模式下的内部工作原理。 如果您已经理解了上一篇文章&#xff0c;那么本文对您来说将会非常简单。 我们将研究 555 定…

C++ - 智能指针 - auto_ptr - unique_ptr - std::shared_ptr - weak_ptr

前言 C当中的内存管理机制需要我们自己来进行控制&#xff0c;比如 在堆上 new 了一块空间&#xff0c;那么当这块空间不需要再使用的时候。我们需要手动 delete 掉这块空间&#xff0c;我们不可能每一次都会记得&#xff0c;而且在很大的项目程序当中&#xff0c;造成内存泄漏…

【合集】Java进阶——Java深入学习的笔记汇总 JVM底层、多线程、类加载 ...

前言 spring作为主流的 Java Web 开发的开源框架&#xff0c;是Java 世界最为成功的框架&#xff0c;持续不断深入认识spring框架是Java程序员不变的追求&#xff1b;而spring的底层其实就是Java&#xff0c;因此&#xff0c;深入学习Spring和深入学习Java是硬币的正反面&…

[代码随想录]二叉树篇

文章目录 1. 二叉树之层序遍历1.1 144-二叉树的前序遍历1.2 94-二叉树的中序遍历1.3 145-二叉树的后序遍历1.4 102-二叉树的层序遍历1.5 107-二叉树的层序遍历II1.6 199-二叉树的右视图1.7* 637-二叉树的层平均值1.8* 429-N叉树的层序遍历1.9 515-在每个树行中找最大值1.10* 11…

【算法挨揍日记】day14——724. 寻找数组的中心下标、238. 除自身以外数组的乘积

724. 寻找数组的中心下标 724. 寻找数组的中心下标 题目描述&#xff1a; 给你一个整数数组 nums &#xff0c;请计算数组的 中心下标 。 数组 中心下标 是数组的一个下标&#xff0c;其左侧所有元素相加的和等于右侧所有元素相加的和。 如果中心下标位于数组最左端&#…

客户成功体系如何构建?请看这7步

⭐简单说两句⭐ 作者&#xff1a;后端小知识 CSDN个人主页&#xff1a;后端小知识 &#x1f50e;GZH&#xff1a;后端小知识 &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; 客户成功体系如何构建&#xff1f;请看这7步 在中国企业服务领域的…

js获取当前月第一天最后一天

【版权所有&#xff0c;文章允许转载&#xff0c;但须以链接方式注明源地址&#xff0c;否则追究法律责任】【创作不易&#xff0c;点个赞就是对我最大的支持】 前言 仅作为学习笔记&#xff0c;供大家参考 总结的不错的话&#xff0c;记得点赞收藏关注哦&#xff01; 目录 …

C++ DAY 5

#include <iostream>using namespace std;class Sofa { private:string sit; public:Sofa(string s "-") :sit(s){cout << "sofa 构造函数" << endl;}void show (){cout << sit << endl;} }; class Bed { private:string sl…