【Spring】本地事务

一、事务的基本性质

  • 原子性:一系列操作整体不可拆分,要么同时成功,要么同时失败。(下订单、减库存、减积分)
  • 一致性:数据在事务的前后,业务整体一致。(存取钱的总数量)
  • 隔离性:事务之间互相隔离。
  • 持久性:一旦事务成功,数据一定会落盘在数据库。

二、事务的隔离级别

事务的隔离级别(Transaction Isolation Levels)定义了在并发执行的事务中,一个事务对其他事务的操作的可见性和影响。SQL标准定义了四种常见的隔离级别,按隔离程度从低到高排序,分别是:

  1. 读未提交(Read Uncommitted)

    • 在此隔离级别下,一个事务可以读取另一个事务尚未提交的修改。这种级别可能导致脏读(Dirty Read),即读取到一个事务未提交的、不一致的数据。
    • 脏读:一个事务读取到另一个事务正在修改但未提交的数据,若第二个事务回滚,则第一个事务读取到的数据不准确。
  2. 读已提交(Read Committed)

    • Oracle和SQL Server的默认隔离级别。
    • 该隔离级别保证一个事务只能读取到已经提交的数据。也就是说,一个事务只能看到其他事务已经提交的结果。
    • 但它仍然存在不可重复读(Non-repeatable Read)的情况。即,在同一事务中,多次读取同一数据时,数据可能会在事务过程中被其他事务修改。
  3. 可重复读(Repeatable Read)

    • 在此隔离级别下,事务中读取的数据在整个事务期间都是一致的,即同一查询多次执行时结果不会变化,避免了不可重复读的问题。
    • 但此级别仍可能出现幻读(Phantom Read)。幻读指的是在同一个事务中,第一次查询某个范围的数据后,第二次查询同一范围时,可能会看到其他事务插入的新的数据行。
    • MYSQL的默认隔离级别。MySQL数据库的InnoDB引擎可以通过next-key locks机制来避免幻读。
  4. 串行化(Serializable)

    • 在该隔离级别下事务都是串行顺序执行的,MySQL数据库的 InnoDB 引擎会给读操作隐式加一把读共享锁,从而避免了脏读、不可重读复读和幻读问题。

示例:

 @Transactional(isolation = Isolation.READ_COMMITTED)- Isolation.READ_UNCOMMITTED:允许脏读。- Isolation.READ_COMMITTED:禁止脏读,允许不可重复读。- Isolation.REPEATABLE_READ:禁止脏读和不可重复读,允许幻读。- Isolation.SERIALIZABLE:禁止所有并发问题(脏读、不可重复读、幻读)。

三、事务的传播行为

传播行为说明适用场景
PROPAGATION.REQUIRED如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务。该设置是最常用的设置。最常用,适用于大多数业务方法。
PROPAGATION.SUPPORTS支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务执行。某些方法可以在事务中执行,也可以在非事务模式下执行,通常用于查询操作。
PROPAGATION.MANDATORY支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。确保方法必须在事务中执行,若外部没有事务,则会抛出异常。
PROPAGATION.REQUIRES_NEW创建新事务,无论当前存不存在事务,都创建新事务。需要独立事务执行的操作,如日志记录或外部系统调用等。
PROPAGATION.NOT_SUPPORTED以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。不希望当前方法在事务中执行的操作,通常用于日志、非数据库操作等场景。
PROPAGATION.NEVER以非事务方式执行,如果当前存在事务,则抛出异常。必须确保方法不在事务中执行。
PROPAGATION.NESTED如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与 PROPAGATION.REQUIRED 类似的操作。支持事务嵌套,适用于需要回滚部分操作但不影响外部事务的场景。

事务传播行为示例:

    @Transactionalpublic void methodA() {methodB();methodC(); }@Transactional(propagation = Propagation.REQUIRED)public void methodB() {}@Transactional(propagation = Propagation.REQUIRES_NEW)public void methodC() {}

事务执行顺序:

假设我们执行 methodA()

  1. 调用 methodA

    • methodA 被调用时,由于 @Transactional 默认使用 Propagation.REQUIRED,它会启动一个事务(假设当前没有事务的话)。
    • 这时,methodA 进入事务上下文。
  2. 调用 methodB

    • methodA 中调用 methodB 时,由于 methodB 的传播行为是 Propagation.REQUIRED,如果已经存在事务(即 methodA 创建的事务),methodB 会加入这个现有事务。
    • 因此,methodBmethodA 会共享同一个事务。
  3. 调用 methodC

    • methodA 中调用 methodC 时,由于 methodC 的传播行为是 Propagation.REQUIRES_NEW,它会始终开启一个新的事务。
    • methodC 的事务会挂起 methodA 中的事务,methodC 会在自己的事务中执行。methodC 执行完后,methodA 的事务会恢复。
    • methodCmethodA / methodB 的事务是独立的,methodC 完成后,methodA 会继续执行。

四、本类方法调用事务失效

同一个对象内事务方法互相调用默认失败,因为绕过了代理对象。相当于b、c的事务不会生效,和a共用一个事务。

示例:

   @Transactional(timeout = 30)public void a(){b();c();}@Transactional(propagation = Propagation.REQUIRED,timeout = 2)public void b(){}@Transactional(propagation = Propagation.REQUIRES_NEW,timeout = 20)public void c(){}

解决:

  1. 引入aop依赖,使用里面的aspectj做动态代理
        <!--引入aop依赖,使用里面的aspectj做动态代理--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>
  1. 开启aspectj动态代理功能,并对外暴露代理对象。以后所有动态代理都是用aspectj创建(即便没有接口也可以创建动态代理)
@EnableAspectJAutoProxy(exposeProxy= true)
  1. 使用动态代理调用
    @Transactional(timeout = 30)public void a(){OrderServiceImpl orderService = (OrderServiceImpl) AopContext.currentProxy();orderService.b();orderService.c();}

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

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

相关文章

初遇Python-----python/anaconda/PyCharm安装应用问题

作为一名医学生,小编之前从未用过python,一直将R视为数据分析的利器,至于到底R好用还是Python好用,一直是广大网友们争论的热点,小编资历尚浅,对此就不予评价了。最近需要对部分数据进行建模工作,奈何三方工具完全基于python语言编写的,迫不得已小编也只能挠头学习了。本…

基于reads的宏基因组与宏转录组医学分析流程正式上线!

随着生物医学领域的快速发展&#xff0c;宏基因组学和宏转录组学正逐渐成为研究微生物群落及其在人体健康与疾病中作用的关键技术。然而&#xff0c;医学研究样品往往存在微生物含量较低的情况&#xff0c;这给数据分析带来了挑战。为了解决这一难题&#xff0c;并适应不断增长…

使用Aria2实现离线下载

最近有需要BT下载&#xff0c;但有的资源很冷门&#xff0c;速度很慢&#xff0c;总不能一直开着电脑下载&#xff0c;于是想到部署个离线下载。想起之前用雨云服务器拿来部署兰空图床感觉效果不错&#xff0c;发现内存剩的还挺多&#xff0c;所以继续压榨一下&#x1f60f; 提…

第三百二十三节 Java线程教程 - Java同步器

Java线程教程 - Java同步器 同步器对象与一组线程一起使用。 它维护一个状态&#xff0c;根据它的状态&#xff0c;它让一个线程通过或强迫它等待。 本节将讨论四种类型的同步器&#xff1a; SemaphoresBarriersLatchesExchangers 信号量 信号量用于控制可以访问资源的线程…

HTB:Active[WriteUP]

目录 连接至HTB服务器并启动靶机 1.How many SMB shares are shared by the target? 使用nmap对靶机TCP端口进行开放扫描 2.What is the name of the share that allows anonymous read access? 使用smbmap通过SMB服务对匿名用户共享权限情况进行扫描 3.Which file has…

vue3【组件封装】S-icon 图标 ( 集成 iconify )

1. 安装依赖 npm i -D iconify/jsonnpm i --save-dev iconify/vue2. 组件封装 src/components/S-icon.vue <script setup lang"ts"> // 搜索图标 https://icon-sets.iconify.design/ import { Icon } from iconify/vue defineProps({icon: {type: String,requ…

AI视觉小车基础--1.开发前的准备

1. 结束开机大程序 为了能够方便体验小车的APP功能&#xff0c;系统中增加了一个程序&#xff0c;此程序集合了APP的控制功能和玩法&#xff0c;所以称做“大程序”&#xff0c;而且在主板系统开机时&#xff0c;此程序会自动启动&#xff0c;所以称做“开机自启动大程序”。 开…

6.传输层协议、ACL

TCP和UDP协议 TCP/IP协议组的传输层协议 TCP(Transmission Control Protocol ) 传输控制协议 UDP&#xff08;User Datagram Protocol &#xff09; 用户数据报协议 TCP协议 TCP是面向连接的、可靠的进程到进程通信的协议 TCP提供全双工服务&#xff0c;即数据可在同一时间双…

避免数据丢失!在NAS上保存Docker容器配置的正确姿势

引言 如果你使用NAS来管理家庭或小型企业的数据,那么Docker容器一定不陌生。它能快速部署各种应用,比如Jellyfin、Plex等多媒体服务器。然而,很多人却踩过一个坑:NAS关机重启后,Docker容器的配置居然丢了!辛苦搭建的环境瞬间化为乌有。别担心,今天就来分享一套实用的技…

【Java的动态代理】

Java中有两种实现动态代理的方式jdk动态代理和CGLIB动态代理 jdk动态代理: 基于接口的动态代理, 目标对象必须实现接口cglib动态代理: 基于字节生成技术(ASM代码生成库), 能在运行时对java类和接口进行扩展实现 那么动态代理这个技术到底能帮我们干啥? 个人感觉这个技术在框…

python怎么安装numpy

1、在python官网https://pypi.python.org/pypi/numpy中找到安装的python版本对应的numpy版本。 例如&#xff1a; python版本是&#xff1a; 下载的对应numpy版本是&#xff1a; 2、将numpy下载到python的安装目录下的scripts文件夹中&#xff1b; 3、然后在cmd中执行以下命…

计算机三级 数据库技术

第一章 数据库应用系统开发方法 1.1 数据库应用系统生命周期 软件工程:软件工程的思想&#xff0c;即用工程的概念、原理、技术和方法对软件生产、开发的全过程进行跟踪和管理 软件开发方法:瀑布模型、快速原型模型、螺旋模型 DBAS生命周期模型 1.2 规划与分析 系统规划与定…

网络编程套接字2

之前我们已经介绍了UDP套接字流程&#xff0c;接下来我们介绍TCP流套接字编程&#xff0c;TCP的一个核心特点&#xff0c;面向字节流&#xff0c;读写数据的基本单位就是字节。 1.API介绍 1.1ServerSocket:是创建TCP服务器Socket的API&#xff08;专门给服务器用&#xff09;…

偌依-防重复提交

其中的使用工具类可去偌依的代码中查找 需要配合 springboot自定义过滤器构建可重复读取inputStream的request&#xff08;来源若依&#xff09; springboot自定义过滤器构建可重复读取inputStream的request&#xff08;来源若依&#xff09;-CSDN博客 定义注解 package co…

3D 数组插值 MATLAB

插值是一种根据现有数据点创建的趋势查找查询数据点值的方法。MATLAB 提供了许多选项来对 N 维数据执行插值。 在本文中&#xff0c;我们将讨论如何借助一些示例在 3D 数组中插入数据。我们将使用 MATLAB 的 interpn&#xff08;&#xff09; 函数来执行插值。 语法 vq interp…

如何在Typora中绘制流程图

如何在Typora中绘制流程图 在撰写文档时&#xff0c;清晰的流程图能极大地提升信息传递的效率。Typora是一款优秀的Markdown编辑器&#xff0c;支持通过Mermaid语法快速绘制流程图。本文将介绍如何在Typora中创建和自定义流程图&#xff0c;帮助你用更直观的方式呈现逻辑结构和…

SpringBoot集成Redis(全流程详解)

前言 通过在SpringBoot中集成Redis&#xff0c;详细梳理集成过程。包括SpringBoot启动过程中&#xff0c;容器的刷新、自动配置的流程、各类注解的处理。 类比在纯Spring中集成Redis&#xff0c;体验SpringBoot自动配置给开发带来了哪些便利。 一、测试样例 1.1配置文件 a…

机器人控制技术、传感器技术、Wi-Fi无线通信技术、AI视觉应用教学和实训: 智能小车车臂教学平台

1、基本介绍 智能车臂教学平台在硬件上采用模块化设计&#xff0c;主控板、运动车体、机械臂、各类传感器等都可以进行拆卸操作&#xff1b;在接口上&#xff0c;采用标准拔插式设计&#xff0c;减少接线&#xff0c;方便组装。使用Wi-Fi与控制软件进行通信&#xff0c;支持遥…

ssm113ssm框架的购物网站+vue(论文+源码)_kaic

毕 业 设 计&#xff08;论 文&#xff09; 题目&#xff1a;网上超市系统设计与实现 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本网上超市系统就是在这…