SpringBoot 全局事务配置

2023-11-17

前言

传统springboot实现事务只需要在方法上添加@Transactional注解,但是需要在所有的service都加上事务,相对比较麻烦,随着项目的庞大,功能模块会随之增多,所以就需要采用AOP的方式实现全局事务处理。
全局事务配置通过AOP切面指定方法前缀切入点,从而对指定的方法统一进行事务控制,根据方法名前缀来匹配到具体方法,进行事务配置

一、什么是事务?

提到事务,你肯定不陌生,和数据库打交道的时候,我们总会用到事务

案例

你要给朋友小王转 100 块钱,而此时你的银行卡只有 100 块钱。转账过程具体到程序里会有一系列的操作,比如查询余额、做加减法、更新余额等,这些操作必
须保证是一体的,不然等程序查完之后,还没做减法之前,你这 100 块钱,完全可以借着这个时间差再查一次,然后再给另外一个朋友转账,如果银行这么整,不就乱了么?这时就要用到 “ 事务 ” 这个概念了。

概念

简单来说,事务就是保证数据操作,要么全部成功,要么全部失败。MySQL 虽然支持多引擎系统,但并不是所有的引擎都支持事务。比如 MySQL 原生的 MyISAM 引擎就不支持事务,这也是 MyISAMInnoDB 取代的重要原因之一。

二、事务的特性(ACID)

  • 原子性(Atomicity):在事务操作中,要么全部成功,要么全部失败。
  • 一致性(Consistency):事务改变前后,状态一致。
  • 隔离性(Isolation):两个事物直接互不干扰。
  • 持久性(Durability):持久到硬盘。

三、隔离性与隔离级别

为什么需要隔离

当数据库上有多个事务同时执行时候,就会出现并发问题:

  • 脏读( dirty read):对于两个事务T1,T2,T1读取了已经被T2更新但还没有被提交的字段之后,若T2回滚,T1读取的内容就是临时且无效的。
  • 不可重复度( non-repeatable read ):对于两个事务T1,T2,T1读取了一个字段,然后T2更新了该字段之后,T1在读取同一个字段,值就不同了。
  • 幻读( phantom read):对于两个事务T1,T2,T1在A表中读取了一个字段,然后T2又在A表中插入了一些新的数据时,T1再读取该表时,就会发现神不知鬼不觉的多出几行了…

为了解决这些问题,就有了 “ 隔离级别 ” 的概念。

隔离级别

重点: 隔离得越严实,效率就会越低。
SQL 标准的事务隔离级别包括:

  • 读未提交( read uncommitted ): 一个事务还没提交时,它做的变更就能被别的事务看到(脏读、不可重复读和幻读的问题都会出现)。
  • 读提交( read committed ): 一个事务提交之后,它做的变更才会被其他事务看到(可以避免脏读,但不可重复读和幻读的问题仍然可能出现)。
  • 可重复读( repeatable read ): 确保事务可以多次从一个字段中读取相同的值,在这个事务持续期间,禁止其他事务对这个字段进行更新(update)。(可以避免脏读和不可重复读,但幻读仍然存在)
  • 串行化( serializable ): 顾名思义是对于同一行记录, “ 写 ” 会加 “ 写锁 ” , “ 读 ” 会加 “ 读锁 ” 。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。

其中 “ 读提交 ” “ 可重复读 ” 比较难理解,所以我用一个例子说明这几种隔离级别。假设数据表 T 中只有一列,其中一行的值为 1 ,下面是按照时间顺序执行两个事务的行为。

mysql> create table T(c int) engine=InnoDB;
insert into T(c) values(1);

在这里插入图片描述
在不同的隔离级别下,事务 A 会有哪些不同的返回结果,也就是图里面 V1 、 V2 、 V3 的返回值分别是什么。

  • 若隔离级别是 “ 读未提交 ” , 则 V1 的值就是 2 。这时候事务 B 虽然还没有提交,但是结果已经被 A 看到了。因此, V2 、 V3 也都是 2 。
  • 若隔离级别是 “ 读提交 ” ,则 V1 是 1 , V2 的值是 2 。事务 B 的更新在提交后才能被 A 看到。所以V3 的值也是 2 。
  • 若隔离级别是 “ 可重复读 ” ,则 V1 、 V2 是 1 , V3 是 2 。之所以 V2 还是 1 ,遵循的就是这个要求:事务在执行期间看到的数据前后必须是一致的。
  • 若隔离级别是 “ 串行化 ” ,则在事务 B 执行 “ 将 1 改成 2” 的时候,会被锁住。直到事务 A 提交后,事务 B 才可以继续执行。所以从 A 的角度看, V1 、 V2 值是 1 , V3 的值是 2 。

好了,概念说完了,下面进入主题,SpringBoot 全局事务配置。

四、SpringBoot 全局事务配置

/**
 * @author lanys
 * @author Think
 * @title: SpringTxAspect
 * @projectName material_cloud
 * @description: Spring 全局事务切面配置
 * @date 2022/11/2 12:18
 */
@Aspect
@Configuration
public class SpringTxAspect {

    /** 切面,根据自己的项目定义不同的表达式execution **/
    private static final String AOP_POINTCUT_EXPRESSION = "execution(* com.material_cloud.short_link.modules.service.impl.*.*(..))";

    @Resource
    private PlatformTransactionManager transactionManager;

    /**
     * 增强(事务)的属性的配置
     *
     * @title: txAdvice
     * @author lanys 2022-11-02
     * @Description: 配置
     * @param
     * @return TransactionInterceptor
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Bean
    public TransactionInterceptor txAdvice() {
        NameMatchTransactionAttributeSource txAttributeS = new NameMatchTransactionAttributeSource();
        RuleBasedTransactionAttribute requiredAttr = new RuleBasedTransactionAttribute();
        // PROPAGATION_REQUIRED:如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中
        requiredAttr.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        // 抛出异常后执行切点回滚
        requiredAttr.setRollbackRules(Collections.singletonList(new RollbackRuleAttribute(Exception.class)));
        //
        RuleBasedTransactionAttribute supportsAttr = new RuleBasedTransactionAttribute();
        // PROPAGATION_SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行
        supportsAttr.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS);
        // 只读事务,不做更新操作
        supportsAttr.setReadOnly(true);

        // 注意:方法名称来自类匹配的到方法【save*, “*”表示匹配任意個字符】
        Map txMethod = new HashMap();
        txMethod.put("insert*", requiredAttr);
        txMethod.put("add*", requiredAttr);
        txMethod.put("update*", requiredAttr);
        txMethod.put("modify*", requiredAttr);
        txMethod.put("remove*", requiredAttr);
        txMethod.put("delete*", requiredAttr);
        txMethod.put("bind*", requiredAttr);
        txMethod.put("unbind*", requiredAttr);
        // readOnly = true
        txMethod.put("select*", supportsAttr);
        txMethod.put("get*", supportsAttr);
        txMethod.put("find*", supportsAttr);
        txMethod.put("query*", supportsAttr);
        txMethod.put("read*", supportsAttr);
        txMethod.put("check*", supportsAttr);
        //
        txAttributeS.setNameMap(txMethod);
        TransactionInterceptor txAdvice = new TransactionInterceptor(transactionManager, txAttributeS);
        return txAdvice;
    }

    /**
     * AOP配置定义切面和切点的信息
     *
     * @title: txAdviceAdvisor
     * @author lanys 2022-11-02
     * @Description: AdvisorBean
     * @return Advisor
     */
    @Bean
    public Advisor txAdviceAdvisor() {
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression(AOP_POINTCUT_EXPRESSION);
        return new DefaultPointcutAdvisor(pointcut, txAdvice());
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SpringBoot 全局事务配置 的相关文章

随机推荐

  • matlab for循环坑

    matlab 用 for 嵌套循环遍历数组时 可能有 bug matlab octave 环境 linux Matlab R2018a 1 windows GNU Octave version 5 2 0 以 for x vector 的形
  • 遍历-字典里面取键

    输入字符串 输出为 字典 输入字符串 并统计字符串重叠单个次数 a 小明456fgdddhhh55adbyjjjjj m for ch in a 从a字符串里面取值 if ch in m 取出来的值如果在 m 里面 m ch 1 m字典里面
  • 词云制作(中文分词+英文)

    英文文本制作词云图 pip install wordcloud filename XX txt 将目标文本文件放入这里 with open filename encoding utf8 as f mytext f read mytext 查
  • 教程:Word中如何让参考文献编号和引用标记都是数字上标

    教程 Word中如何让参考文献编号和引用标记都是上标 更新历史 20190509 首次发布 使用Microsoft Word写论文之类的文档的时候 经常需要列出参考文献 并对它们进行引用 有时候 格式规范要求我们将参考文献编号和引用标记都变
  • vscode 注释

    这篇文章主要介绍了vscode添加注释的方法 具有一定借鉴价值 需要的朋友可以参考下 希望大家阅读完这篇文章后大有收获 下面让小编带着大家一起了解一下 1 在 Vscode 扩展商店中搜索koroFileHeader 点击安装 2 注释模板
  • 计算机视觉应该怎样入门?

    知乎问答 计算机视觉应该怎样入门 目录 第一阶段 技术基石 图像处理基础 图像处理进阶 第二阶段 深度学习 神经网络初步与调参技巧 深度卷积神经网络原理与实践 图像搜索技术 大规模车辆图片搜索 重识别 第三阶段 重点攻坚 目标检测及其在无人
  • socket 编程

    为什么80 的码农都做不了架构师 gt gt gt 利用windows api进行最原始的socket编程 服务端 WSAStartup ListenSock socket bind listen ListenSock acceptSock
  • 实战3-淘宝用户行为分析及可视化

    淘宝用户行为分析及可视化 目录 淘宝用户行为分析及可视化 分析背景 明确问题 读取和理解数据 数据预处理 数据分析与可视化 用户行为分析 日PV和日UV PV与UV相关性 可视化 时PV和时UV 相关性 可视化 不同行为类型用户PV分析 操
  • stata协整检验结果怎么看_面板数据协整检验

    5 3 1裴德劳因 Pedroin 检验 裴德劳因 Pedroin 1999 提出了以恩格尔 Engle 和格兰杰 Granger 二步法为基础的面板数据的协整检验方法 该方法利用协整方程的回归残差构造了七个统计量来检验面板数据之间的协整关
  • vue 引入高德地图 amap 报错:jsapi 不生效 INVALID_USER_SCODE

    高德地图 JSAPI key 和安全密钥的使用 自2021年12月02日升级 升级之后所申请的 key 必须配备安全密钥 jscode 一起使用 报错 高德地图jsapi不生效 INVALID USER SCODE 是因为没有设置安全密钥
  • 全排列

    举例 123的全排列 123 132 213 231 321 312 全排列的个数为 n STL 实现 char s 50 cin gt gt s int k strlen s sort s s k cout lt
  • IDEA中Sprint MVC环境配置<mvc:default-servlet-handler/>报错

    问题描述 在配置applicationContext xml文件时 mvc default servlet handler 出现问题不能正常使用 提示未声明 但是mvc其他的都可以正常使用 比如 mvc annotation driven
  • Python中operator模块的操作

    Operator模块提供了一系列与Python自带操作一样有效的函数 例如 operator add x y 和表达式x y是等效的 那些特殊类的方法都有自己的函数名 为了方便起见 一些函数名是没有前导和后置 在接下来讨论的函数涉及对象比较
  • 计算机毕业设计选题\开题\项目\论文\答辩一套玩转毕业设计

    毕业设计选题 一 毕业设计整体流程介绍 二 毕业设计选题方式 三 毕业设计时间安排与选题技巧 1 时间安排 根据往年毕设辅导对同学们的了解毕设项目加上论文一般需要花费三到七个月左右时间 基础差的同学应尽量提前准备 2 毕设选题的时候同学们要
  • heartbeat+mysql双主复制实现高可用

    实验环境 一 搭建主主复制环境 1 1实验环境 两台机器事先都已经装好了MySQL单实例 IP 10 192 203 201 10 192 203 202 端口都是3307 二者的端口号需要保持一致 否则在最后用vip连接的时候 不能使用相
  • 判断变量是否为数组的几种方法

    1 isArray 方法 isArray 方法用于判断一个对象是否为数组 如果对象是数组返回 true 否则返回 false Array isArray arr true 2 对象原型 通过原型链判断是否具有和数组同一原型链的顶端 arr
  • Linux wget 命令下载文件示例

    inux系统中的wget是一个下载文件的工具 它用在命令行下 wget支持HTTP HTTPS和FTP协议 可以使用HTTP代理 所谓的自动下载是指 wget可以在用户退出系统的之后在后台执行 wget 非常稳定 它在带宽很窄的情况下和不稳
  • IDEA启动报错:An attempt was made to call a method that does not exist. The attempt was made from ...

    项目场景 Springboot项目 问题描述 项目无法启动 至上一次启动成功未更改代码 排除代码错误原因 具体报错如下 可能是项目未关闭完全 又重启了项目等多种原因触发这个问题 APPLICATION FAILED TO START Des
  • SourceTree系列5:贮藏和修复Bug

    1 贮藏 在切换分支时 要确保该分支已经提交 如果当前develop分支可以提交 无疑是最好的选择 但是 如果当前不能提交呢 此时我们可以使用贮藏功能 贮藏功能就是对现在的更改进行备份 注意仅仅是对更改进行备份 使用贮藏功能后 会让当前分支
  • SpringBoot 全局事务配置

    前言 传统springboot实现事务只需要在方法上添加 Transactional注解 但是需要在所有的service都加上事务 相对比较麻烦 随着项目的庞大 功能模块会随之增多 所以就需要采用AOP的方式实现全局事务处理 全局事务配置通