4. Mybatis 事务和Spring事务关系

news2024/11/17 7:54:32

大体上分为两种情况:方法上添加了事务注解@Transactional 和方法上没有添加事务注解@Transactional。

  • 添加了@Transactional 注解的在注入 bean 的时候就会被创建代理类,在代理类中使用增强逻辑进行事务处理。
  • 没有添加@Transactional 注解的,在 SqlSession 执行 sql方法的时候,执行完sql 后提交事务。

方法上没有事务注解@Transactional

我们需要知道大体流程:

  1. 与Spring 框架集成后的 mybatis 的 SqlSession 会被SqlSessionTemplate代理。即当我们使用 mybatis 执行 sql 的时候必然会走 SqlSessionTemplate 的 invoke 方法
  2. 在SqlSessionTemplate的 invoke 方法中。会先获取一个 Session 然后在执行被代理的方法(执行增删改查的sql)。
  3. 执行完Sql 之后会判断是否有Spring事务,如果没有Spring事务就提交。如果有 Spring 事务,当前 invoke 方法什么也不做,事务交给 Spring 事务管理器来做。

这个时候sql 执行完自动提交。SQL 执行失败就失败。这个时候 sql 的执行会走SqlSession 的代理逻辑 SqlSessionTemplate 中的invoke 方法。

image

方法上有事务注解@Transactional

这个时候会用到 Spring 的事务管理器。

当然首先是 AOP 针对@Transactional 注解进行代理。在 AOP 的 BeanPostProcessor 扫描@Transactional 注解的时候,会解析目标类和方法的属性并包装成事务属性对象,并对含有 Transactional 注解的类创建动态代理对象。

动态代理对象的增强逻辑或者叫代理逻辑为TransactionInterceptor。

此外我们还需要知道:

Mybatis事务和Spring事务的沟通桥梁就是 TransactionSynchronizationManager。TransactionSynchronizationManager会和DataSourceTransactionManager进行交互。

Transactional的代理逻辑

入口是TransactionInterceptor​,TransactionInterceptor 本身是个Advisice。是AOP的切面。其切面逻辑主要是调用抽象父类TransactionAspectSupport的invokeWithinTransaction​这个方法(以事务的方式调用这个方法)。

  1. 获取AnnotationTransactionAttributeSource​ 事务属性源。

  2. 获取事务属性,从事务属性源里获取当前被调用方法的事务属性。

  3. 获取事务管理器。根据事务管理器的类型选择对应的逻辑执行。

  4. 获取事务唯一标识: joinpointIdentification​ 这个算是事务的唯一key吧。通常是类的全路径名+方法名

  5. 创建一个事务:如果该方法对应的事务属性不为空,调用createTransactionIfNecessary​方法。该方法未必会一定创建事务,如果事务存在就不会创建事务。

    1. 如果事务存在,调用getTransaction​获取已存在的事务。并按照事务传播机制进行处理

      1. PROPAGATION_NEVER​:抛异常
      2. PROPAGATION_NOT_SUPPORTED​:挂起当前事务
      3. PROPAGATION_REQUIRES_NEW​:挂起当前事务,开启一个新的事务
      4. 。。。
    2. 处理事务超时时间

    3. 如果没有发现已存在的事务,处理传播机制。

      1. startTransaction开始执行事务:PROPAGATION_REQUIRED

        1. doBegin方法中将事务自动提交改为false。
  6. invocation.proceedWithInvocation()执行增强方法(环绕通知);

  7. 如果事务方法执行未发生异常,则调用commitTransactionAfterReturning(txInfo)进行提交事务;

  8. 如果事务方法执行发生异常,则调用completeTransactionAfterThrowing(txInfo, ex)进行异常回滚;

Mybatis ->TransactionSynchronizationManager

Mybatis事务和Spring事务的沟通桥梁就是 TransactionSynchronizationManager。TransactionSynchronizationManager会和DataSourceTransactionManager进行交互。

我们先看一下mybatis是如何和TransactionSynchronizationManager对接的。一切都在SqlSessionTemplate这个类的反射逻辑中。

SqlSessionTemplate

SqlSessionTemplate禁用掉了手动事务操作。

public void commit(boolean force) {
    throw new UnsupportedOperationException("Manual commit is not allowed over a Spring managed SqlSession");
}

public void rollback() {
    throw new UnsupportedOperationException("Manual rollback is not allowed over a Spring managed SqlSession");
}
获取sqlSession的逻辑

在MybatisAutoConfiguration中创建了SqlSessionTemplate代理DefaultSqlSession以实现DefaultSqlSession的复用。

SqlSessionTemplate是SqlSession的实现之一。其目的主要是适应Spring的容器化环境和Spring 事务。

在SqlSessionTemplate的代理逻辑中会有获取 SqlSession的逻辑。这里会优先从TransactionSynchronizationManager获取一个SqlSession。如果获取不到,再创建一个并注册到TransactionSynchronizationManager中。下次直接用就可以。

public static SqlSession getSqlSession(SqlSessionFactory sessionFactory, ExecutorType executorType, PersistenceExceptionTranslator exceptionTranslator) {
    Assert.notNull(sessionFactory, "No SqlSessionFactory specified");
    Assert.notNull(executorType, "No ExecutorType specified");
    SqlSessionHolder holder = (SqlSessionHolder)TransactionSynchronizationManager.getResource(sessionFactory);
    SqlSession session = sessionHolder(executorType, holder);
    if (session != null) {
        return session;
    } else {
        LOGGER.debug(() -> {
            return "Creating a new SqlSession";
        });
        session = sessionFactory.openSession(executorType);
        registerSessionHolder(sessionFactory, executorType, exceptionTranslator, session);
        return session;
    }
}
判断sqlSession是否支持事务
public static boolean isSqlSessionTransactional(SqlSession session, SqlSessionFactory sessionFactory) {
    Assert.notNull(session, "No SqlSession specified");
    Assert.notNull(sessionFactory, "No SqlSessionFactory specified");
    SqlSessionHolder holder = (SqlSessionHolder)TransactionSynchronizationManager.getResource(sessionFactory);
    return holder != null && holder.getSqlSession() == session;
}

DataSourceTransactionManager -> TransactionSynchronizationManager

DataSourceTransactionManager 是Spring事务中事务管理器​PlatformTransactionManager​的一种实现。

PlatformTransactionManager有三个方法分别是:getTransaction、commit、rollback。由于getTransaction最为简洁直观,所以我们单看这个类就可以。

protected Object doGetTransaction() {
	DataSourceTransactionObject txObject = new DataSourceTransactionObject();
	txObject.setSavepointAllowed(isNestedTransactionAllowed());
	ConnectionHolder conHolder =
			(ConnectionHolder) TransactionSynchronizationManager.getResource(obtainDataSource());
	txObject.setConnectionHolder(conHolder, false);
	return txObject;
}

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

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

相关文章

文件模块常用api

文件模块常用api 文件夹常用操作 文件夹操作 fs.mkdir fs.rmdir 需要是空目录 题目:递归删除目录* 串行/并行删除文件*

肯尼斯·里科《C和指针》第6章 指针(4)实例

肯尼斯里科《C和指针》第6章 指针&#xff08;1&#xff09;-CSDN博客 肯尼斯里科《C和指针》第6章 指针&#xff08;2&#xff09;-CSDN博客 肯尼斯里科《C和指针》第6章 指针&#xff08;3&#xff09;-CSDN博客 6.12 实例 /* ** 计算一个字符串的长度。 */ #include <…

SSL证书怎么选?

首先&#xff0c;我们需要理解不同类型的SSL证书及其费用差异。通常情况下&#xff0c;SSL证书分为域名验证型&#xff08;DV&#xff09;、组织验证型&#xff08;OV&#xff09;和企业验证型&#xff08;EV&#xff09;三种。其中&#xff0c;DV证书是最常见的类型&#xff0…

入驻商城小程序系统源码:众多自定义组件以及营销插件随心搭,独立部署,带完整的搭建教程

现如今&#xff0c;互联网在不断的发展&#xff0c;小程序已成为电商行业的重要战场。入驻商城小程序系统源码正是基于这一背景&#xff0c;为用户提供了一套功能强大、易于定制的电商解决方案。该源码拥有众多自定义组件和营销插件&#xff0c;支持独立部署&#xff0c;并附带…

芯课堂 | 华芯微特MCU在PCB板级设计中对ISP引脚的应用

1.应用描述 ISP&#xff08;In System Programming&#xff09;&#xff0c;在系统编程&#xff0c;使用片内驻留出厂引导程序&#xff08;BootROM&#xff09;配合UART / SPI等外设进行烧录。 华芯微特全系MCU的ISP操作说明&#xff1a;当芯片上电后检测到 ISP 引脚持续 5ms…

聚甲基丙烯酸甲酯PMMA的特性有哪些?UV胶水能够粘接聚甲基丙烯酸甲酯PMMA吗?又有哪些优势呢?

聚甲基丙烯酸甲酯&#xff08;Polymethyl Methacrylate&#xff0c;PMMA&#xff09;&#xff0c;又称丙烯酸甲酯&#xff0c;是一种常见的透明塑料&#xff0c;具有许多特性&#xff0c;使其在各种应用领域中广泛使用。以下是PMMA的一些主要特性&#xff1a; 1. 优异的透明性&…

【极光系列】springBoot集成Hibernate

【极光系列】springboot集成hibernate gitee地址 直接下载可用 https://gitee.com/shawsongyue/aurora.git 模块&#xff1a;aurora_hibernate mysql安装教程 参考我另外一篇文章&#xff0c;直接下载安装 https://blog.csdn.net/weixin_40736233/article/details/1355829…

入站请求负载均衡解决方案 LVS 的介绍

概述 LVS 简介 LVS&#xff08;Linux Virtual Server&#xff09;即 Linux 虚拟服务器&#xff0c;是一个虚拟的服务器集群系统。 通过 LVS 的负载均衡技术和 LINUX 操作系统可以实现一个高性能、高可用的 LINUX 服务器集群&#xff0c;它具有良好的可靠性、可扩展性和可操作性…

PVE虚拟机安装qemu guest agent

pve虚拟机安装guest agent&#xff0c;使web平台可以直接显示虚拟机的ip&#xff0c;方便管理。 一、虚拟机需开启Qemu代理 首先&#xff0c;虚拟机需开启Qemu代理&#xff0c;需要关闭虚拟机再启动虚拟机并安装agent。网上有些文章说要把网卡配置为virtio&#xff0c;经测试是…

MATLAB - 计算关节扭矩以平衡端点力和力矩

系列文章目录 前言 产生力矩以平衡作用在平面机器人末端执行器体上的端点力。要使用各种方法计算关节力矩&#xff0c;请使用刚体树机器人模型的几何雅各比&#xff08;geometricJacobian&#xff09;和反动力学&#xff08;inverseDynamics&#xff09;对象函数。 一、初始化…

在IntelliJ IDEA上使用通义灵码(TONGYI Lingma)

参考链接&#xff1a; 通义灵码产品介绍_智能编码助手_AI编程_云效(Apsara Devops)-阿里云帮助中心 【IDEA如何使用通义灵码&#xff1f;】_idea 通义灵码-CSDN博客 1. 简介 1.1 定义 通义灵码&#xff0c;是阿里云出品的一款基于通义大模型的智能编码辅助工具&#xff0c;提…

单细胞转录组学对代谢功能障碍相关脂肪变性肝病的类器官模型进行分析

前言 最近接触比较多肝纤维化项目&#xff0c;包括空转、单细胞和普通的BULK转录组&#xff0c;本文是肝脏疾病类器官构建&#xff0c;所以结果是比较确定的&#xff0c;只是对比不同处理和培养哪种效果更好&#xff0c;适合了解纤维化进展和哪些分子和细胞参与&#xff0c;以…

基于协方差矩阵自适应演化策略(CMA-ES)的高效特征选择

特征选择是指从原始特征集中选择一部分特征&#xff0c;以提高模型性能、减少计算开销或改善模型的解释性。特征选择的目标是找到对目标变量预测最具信息量的特征&#xff0c;同时减少不必要的特征。这有助于防止过拟合、提高模型的泛化能力&#xff0c;并且可以减少训练和推理…

CANFD数据记录仪在新能源汽车复杂路测下的应用

CANFD数据记录仪在新能源汽车复杂路测下的应用 汽车制造商在生产预批量阶段的耐久性测试中,为了检测潜在故障,必须让车辆在严酷的路况和环境下接受测试。为确保能回溯故障发生的现场情况,我们需要对测试数据精准记录与储存。这些数据是新车型优化迭代的关键,也是确保产品质量的…

【优选算法】滑动窗口 {何时使用滑动窗口?如何使用滑动窗口?如何确定更新结果的时机?滑动窗口是如何提高效率的?相关编程题解析}

一、经验总结 何时使用滑动窗口&#xff1f; 在使用暴力解法解题时&#xff0c;发现可以将其优化为同向双指针&#xff0c;既可以使用滑动窗口。 如何使用滑动窗口&#xff1f; 1. 定义窗口控制变量n&#xff0c;进窗口&#xff0c;判断&#xff0c;出窗口都需要操作窗口控制…

天软特色因子看板 (2024.01 第7期)

该因子看板跟踪天软特色因子A04001(当日趋势强度)&#xff0c;该因子为反映股价走势趋势强弱&#xff0c;用以反映股价走势趋势强弱&#xff0c;abs(值)越接近1&#xff0c;趋势 性越强&#xff0c;符号代表涨跌方向。 今日为该因子跟踪第7期&#xff0c;跟踪其在SW801050 (申万…

Open CV 图像处理基础:(六)在Java中使用 Open CV进行图片翻转和图片旋转

在Java中使用 Open CV进行图片翻转和图片旋转 目录 在Java中使用 Open CV进行图片翻转和图片旋转前言图片翻转函数代码示例其它翻转方向垂直翻转两轴翻转 图片旋转函数代码示例 Open CV 专栏导航 前言 在Java中使用OpenCV进行图片翻转和旋转是一种基本的图像处理技术&#xff0…

机器学习根据金标准标记数据-九五小庞

根据金标准标记数据是一种在机器学习和数据科学中常见的操作&#xff0c;主要用于评估分类模型的性能。其基本步骤如下&#xff1a; 收集数据&#xff1a;首先需要收集相关领域的原始数据&#xff0c;这些数据通常来自不同的来源和渠道。数据清洗和预处理&#xff1a;在这一步…

常见的限流算法

本文已收录至我的个人网站&#xff1a;程序员波特&#xff0c;主要记录Java相关技术系列教程&#xff0c;共享电子书、Java学习路线、视频教程、简历模板和面试题等学习资源&#xff0c;让想要学习的你&#xff0c;不再迷茫。 天下武学出同源 正所谓天下武学殊途同归&#xff…

怎么批量重命名图片?分享3个高效方法!

怎么批量重命名图片&#xff1f;在日常生活中&#xff0c;将图片批量重命名是一项非常实用的操作。有时候我们拍摄或收集了很多图片&#xff0c;需要对其进行整理和归类。通过批量重命名&#xff0c;我们可以快速为图片添加序号、日期或其他标识&#xff0c;使其更有条理。此外…