在spring事务中扩展业务操作;spring事务同步器TransactionSynchronizationManager

news2024/11/16 15:27:53

概述

业务上经常会有一些需求是需要在某个数据库操作事务提交之后再去操作。

我常用的就方式有@TransactionalEventListenerTransactionSynchronizationManager.

其实@TransactionalEventListener背后使用的也是TransactionSynchronizationManager

注意点:在afterCompletion方法中已经脱离当前事务了,如果想确保其中的方法也在一个事务中,那么就需要开启一个新事务.
在使用 >= spring 5.2是可以用org.springframework.transaction.support.TransactionTemplate#execute方法,里面会新开启一个事务。在小于上述版本时,可以手动开启事务来控制.

使用demo

//fallbackExecution = true代表没有事务的时候也监听
@TransactionalEventListener(value = {xxx.class}, fallbackExecution = true)
@Order(Ordered.HIGHEST_PRECEDENCE)
public void onApplicationEvent(xxx event) {

    log.info("监听成功,xxxxxx");
	//xxxxx

}

TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
            @Override
            public void afterCompletion(int status) {
                switch (status) {
                    case 0:
                        // 外部方法事务提交后执行的业务逻辑
                        break;
                    case 1:
                        // 外部方法事务回滚后执行的业务逻辑
                        break;
                    case 2:
                        // 外部方法事务异常时执行的业务逻辑
                        break;
                }
                TransactionSynchronization.super.afterCompletion(status);
            }
        });

TransactionSynchronizationManager(事务同步器)分析

平时使用的时候都是直接用注解@Transactional,一般也知道是spring aop帮我们开启了事务,其中aop拦截使用事务注解的方法后使用的就是TransactionSynchronizationManager.

我用的是mybatis-spring-2.0.7,就从mybtais获取connection来入手了

org.mybatis.spring.transaction.SpringManagedTransaction#openConnection在从连接池获取connection的时候会判断是否开启了事务,如果已开启,那么会将连接暂时绑定到事务同步管理器中.

所谓的绑定其实就是塞到了一个threadLocal中和当前线程进行了一个关联。

业务中对事务的扩展方法通常都是在TransactionSynchronization的方法中执行的.

org.springframework.transaction.support.AbstractPlatformTransactionManager#triggerAfterCompletion中可以看到会将所有之前注册的同步事务操作按照List中的顺序(注册顺序)依次调用.

最后在org.springframework.transaction.support.AbstractPlatformTransactionManager#processCommit中的finally中可以看到对各项资源进行了释放,意味着我们仍旧可以在这之前拿到connection连接进行操作db

获取连接绑定connection给TransactionSynchronizationManager
在这里插入图片描述

TransactionSynchronization 扩展点

public interface TransactionSynchronization extends Ordered, Flushable {

    /** Completion status in case of proper commit. */
    // 事务提交状态
    int STATUS_COMMITTED = 0;

    /** Completion status in case of proper rollback. */
    // 事务回滚状态
    int STATUS_ROLLED_BACK = 1;

    /** Completion status in case of heuristic mixed completion or system errors. */
    // 事务异常状态
    int STATUS_UNKNOWN = 2;

    /**
     * 当前事务挂起时触发
     * Supposed to unbind resources from TransactionSynchronizationManager if managing any.
     * @see org.springframework.transaction.reactive.TransactionSynchronizationManager#unbindResource
     */
    default void suspend() {
    }

    /**
     * 当前事务恢复时触发(结束挂起时)
     * Supposed to rebind resources to TransactionSynchronizationManager if managing any.
     * @see org.springframework.transaction.reactive.TransactionSynchronizationManager#bindResource
     */
    default void resume() {
    }

    /**
     * 当前事务刷新时触发
     * 将基础会话刷新到数据存储区(如果适用),比如Hibernate/JPA的Session
     * @see org.springframework.transaction.TransactionStatus#flush
     */
    @Override
    default void flush() {
    }

    /**
     * 当前事务提交前触发,此处若发生异常,会导致回滚。
     * @see #beforeCompletion
     */
    default void beforeCommit(boolean readOnly) {
    }

    /**
     * 当前事务完成前触发。
     * 在beforeCommit之后,commit/rollback之前执行。即使异常,也不会回滚。
     * @see #beforeCommit
     * @see #afterCompletion
     */
    default void beforeCompletion() {
    }

    /**
     * 当前事务提交后触发
     */
    default void afterCommit() {
    }

    /**
     * 当前事务完成后触发
     * 通过status的value指定具体的触发时机(即上面的三个属性)
     */
    default void afterCompletion(int status) {
    }
}

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

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

相关文章

爬虫(Requests库get和post应用)

Requests库 介绍 Requests是Python中用于进行HTTPS请求的库。它提供了一种简单直观的API,用于发送HTTP,HTTPS请求和处理响应。 request.get()函数 参数 url,一般放置需要请求的URL headers,一般用于User-agent(UA…

制定CRM战略流程是哪些?

CRM战略是企业为了提升核心竞争力,在市场、销售、客户管理等方面开展的一系列改善、创新或转型的措施。目的是建立和维护与客户的关系,增加企业的收入。那么,企业如何制定CRM战略呢? 1、深入了解客户需求 企业需要了解其目标客户…

【算法总结】——子集型回溯

文章目录 子集型回溯例题1——78.子集代码模板1代码模板2 例题2——131.分割回文串代码模板1代码模板2补充:怎么判断回文串双指针dp提前处理 参考资料 子集型回溯 主要学习 分别从 输入 和 答案 去思考的两种代码模板。 例题1——78.子集 例题:78. 子集…

JavaSE基础语法--数组(1)

数组的定义与使用 数组就是存储相同数据类型的一组数据。它有如下特点: 1.数组中存放的数据是一样的 2.数组的空间是连续的 3.每个空间有自己的编号,其实位置的编号为0,即数组的下标 那么在Java里面如何定义一个数组呢? 假设…

【Python入门】Python循环语句(for循环的嵌套应用)

前言 📕作者简介:热爱跑步的恒川,致力于C/C、Java、Python等多编程语言,热爱跑步,喜爱音乐的一位博主。 📗本文收录于Python零基础入门系列,本专栏主要内容为Python基础语法、判断、循环语句、函…

行为型模式--中介者模式

目录 概述 结构 案例实现 优缺点 优点: 缺点: 使用场景 概述 一般来说,同事类之间的关系是比较复杂的,多个同事类之间互相关联时,他们之间的关系会呈现为复 杂的网状结构,这是一种过度耦合的架构&a…

深入理解深度学习——BERT派生模型:跨语言模型XLM(Cross-lingual Language Model)

分类目录:《深入理解深度学习》总目录 BERT本应在语义理解上具有绝对优势,但其训练语料均为英语单语,受限于此,早期的BERT只在英语文本理解上有优势。随着全球化进程的加速,跨语言的预训练语言模型也具有非常重要的应用…

seldom之数据驱动

seldom之数据驱动 如果自动化某个功能,测试数据不一样而操作步骤是一样的,那么就可以使用参数化来节省测试代码。 seldom是我在维护一个Web UI自动化测试框,这里跟大家分享seldom参数化的实现。 GitHub:GitHub - SeldomQA/seld…

idea设置项目编码为utf8

设置当前项目的编码为utf8 File -> Settings -> Editor -> File Encoding: 设置新建项目的编码为utf8 File -> New Projects Setup -> Settings for New Projects:

Flutter系列(九)ListView实现新闻列表和正文布局

基础工程: Flutter系列(四)底部导航顶部导航图文列表完整代码_摸金青年v的博客-CSDN博客 相关文章: Flutter系列(七)ListView 图文列表详解_flutter 图文列表_摸金青年v的博客-CSDN博客 一、前言 本文用flutter实现新闻…

注册 Google 邮箱(最新:保姆级教程)

文章目录 1、我们使用浏览器打开谷歌邮箱官网(gmail.google.com),进入谷歌邮箱的登录主页,我们点击左下方的创建账号按钮,选择个人用途 2、在进入的界面我们不要着急填写资料,我们先修改语言,点…

(2023,3D 场景生成器 Infinigen)使用程序化生成的无限逼真世界

Infinite PhotorealisticWorlds using Procedural Generation 公众号:EDPJ 目录 0. 摘要 1. 简介 2. 相关工作 3. 方法 4. 实验 参考 S. 总结 S.1 主要思想 S.2 方法 S.3 场景生成 0. 摘要 我们介绍 Infinigen,一个自然世界逼真 3D 场景的…

Verilog | 除法--试商法

试商法 采用试商法实现除法运算,对于32位的除法,需要至少32个时钟周期才能得到除法结果。下面是试商法的一般过程。 设被除数是m,除数是n,商保存在s中,被除数的位数是k,其计算步骤如下(为了便…

leetcode814. 二叉树剪枝(java)

二叉树剪枝 leetcode814. 二叉树剪枝题目描述DFS 深度优先遍历 二叉树专题 leetcode814. 二叉树剪枝 来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/binary-tree-pruning 题目描述 给你二叉树的根结点 root &#xff0c…

《机器学习公式推导与代码实现》chapter17-kmeans

《机器学习公式推导与代码实现》学习笔记,记录一下自己的学习过程,详细的内容请大家购买作者的书籍查阅。 聚类分析和k均值聚类算法 聚类分析(cluster analysis)是一类经典的无监督学习算法,在给定样本的情况下,聚类分析通过度量…

【半监督:交叉分辨率:解纠缠】

Cross-Resolution Semi-Supervised Adversarial Learning for Pansharpening (用于泛锐化的交叉分辨率半监督对抗学习) 现有的基于深度神经网络(DNN)的方法已经产生了良好的泛锐化图像。然而,监督DNN为基础的泛锐化方…

卷积是什么

参考: 【官方双语】那么……什么是卷积?https://www.bilibili.com/video/BV1Vd4y1e7pj/ [建议看完] x.1 一维卷积 一维卷积,即对于两个向量的卷积,就是将向量翻转后,从前向后滑动,相乘再相加。 x.2 二维卷…

Spring Boot启动原理

Spring Boot的自动配置为我们提供了快捷方便的方式来运行Spring应用,但很多开发者对其内部启动原理还不是很明白。这篇博客旨在解开Spring Boot的神秘面纱,帮助大家理解它的启动原理。 入口类和注解 我们的Spring Boot应用通常从一个主类开始&#xff…

感知机(Perceptron)底层原理

1.感知机(Perceptron)底层原理 声明:笔记来源于《白话机器学习的数学》 感知机是接受多个输入后将每个值与各自权重相乘,最后输出总和的模型。 单层感知机因过于简单,无法应用于实际问题,但它是神经网络和深…

8个很少用,但却很好用的 Python 库!

本文介绍一些我们可能很少听过,但是对于特定问题或者特定任务来说,可能会非常有帮助的 Python 库 技术交流 技术要学会分享、交流,不建议闭门造车。一个人可以走的很快、一堆人可以走的更远。 好的文章离不开粉丝的分享、推荐,文…