4. Mybatis 事务和Spring事务关系

大体上分为两种情况:方法上添加了事务注解@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.mzph.cn/news/623393.shtml

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

相关文章

【JaveWeb教程】(26) Mybatis基础操作(新增、修改、查询、删除) 详细代码示例讲解(最全面)

目录 1. Mybatis基础操作1.1 需求1.2 准备1.3 删除1.3.1 功能实现1.3.2 日志输入1.3.3 预编译SQL1.3.3.1 介绍1.3.3.2 SQL注入1.3.3.3 参数占位符 1.4 新增1.4.1 基本新增1.4.2 主键返回 1.5 更新1.6 查询1.6.1 根据ID查询1.6.2 数据封装1.6.3 条件查询1.6.4 参数名说明 1. Myb…

如何打赢稳定性之战?

文章目录 前言为什么总会出现问题呢?如何证明你的稳定性做的有效果?既是持久战,也是防御战1. 提前建筑好防御工事2. 以攻为守3. 找外部支援和配合 前言 随着23年年末期间,各大厂争先恐后的出现的各种线上故障,一时间“…

帆软使用总结-动态分组背景变色

1.开发界面设计 提示: ROUNDUP((ROW() - M) / N, 0) % 2 0row() 获取当前行号 M 标题行数 N 间隔行数 ROUNDUP() 向上取整 如果被2整除,改变背景颜色 当前公式:ROUNDUP((ROW() - 2) / 3, 0) % 2 02.效果演示

Python while循环实现猜字谜游戏

python的while更多地应用于程序的一般性循环,而不是遍历迭代对象。与其他的计算机编程语言不同,python没有do...while这样的while循环。接下来,我们将详细介绍一下Python的while循环,并用寥寥数行代码开发一个小游戏,作…

【题解】—— 每日一道题目栏

2024.1 【题解】—— LeetCode一周小结1 1. 1599. 经营摩天轮的最大利润 2. 466. 统计重复个数 3. 2487. 从链表中移除节点 4. 2397. 被列覆盖的最多行数 5. 1944. 队列中可以看到的人数 6. 2807. 在链表中插入最大公约数 7. 383. 赎金信 【题解】—— LeetCode一周小…

【前端框架】Vue2合集

一、Vue快速上手 1、Vue概念 vue 是一个用于构建用户界面的渐进式框架&#xff0c;由数据驱动 vue 的两种使用方式 vue 核心包开发&#xff1a;局部模块改造vue 核心包与 vue 插件 工程化开发&#xff1a;整站 开发 2、 创建实例 1、准备容器 <div id"app"&…

网站万词霸屏推广系统源码:实现关键词推广,轻松提高关键词排名,带完整的安装部署教程

现如今&#xff0c;互联网的快速发展&#xff0c;网站推广成为企业网络营销的重要手段。而关键词排名作为网站推广的关键因素&#xff0c;一直备受关注。罗峰给大家分享一款网站万词霸屏推广系统源码&#xff0c;该系统可实现关键词推广&#xff0c;有效提高关键词排名&#xf…

【教3妹学编程-算法题】回文串重新排列查询

3妹&#xff1a;好冷啊&#xff0c; 冻得瑟瑟发抖啦 2哥 : 这已经是你今年的第几次抖啦&#xff1f; 3妹&#xff1a;昨天20度&#xff0c;今天7度&#xff0c;直降13度呢&#xff0c;能不抖嘛 2哥 : 继哈尔滨之后&#xff0c;全国各地的城市也在发展旅游业。 河北喊话赵丽颖回…

使用mamba替换conda和anaconda配置环境安装软件

使用mamba替换miniconda和anaconda&#xff0c;原因是速度更快&#xff0c;无论是创建新环境还是激活环境 conda、mamba、anaconda都是蟒蛇的意思… 下载mambaforge wget https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-Linux-x86_64.sh ba…

python 八大排序_python-打基础-八大排序

## 排序篇 #### 二路归并排序 - 介绍 - 归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。归并排序是一种稳定的排序方法。将已有序的子序列合并&#xff0c;得到完全有序的序列&#xff1b;即先使每个子序列…

乐意购项目前端开发 #3

一、icon的使用 前往网站挑选要的图标 iconfont-阿里巴巴矢量图标库https://www.iconfont.cn/?spma313x.manage_type_myprojects.i3.2.2f173a81fQSVOU 创建项目添加图标 选择Font Class 下载到本地 解压后会看到这个页面 在asserts目录下创建iconfont目录,然后将最底下的6…

数据库第一次作业

1.创建一个英雄表 create table t_hero ( id int primary key auto_increment, name varchar(10) unique not null, gender char(5) check (gender in (男,女)), grade char(5) default 5星, groups char(5) check (groups in (毁灭,巡猎,智识,存护,…

GPT与文心一言大模型的比较与展望

目录 前言1 GPT和文心一言简介2 GPT和文心一言的技术原理和基础架构3 GPT和文心一言的模型规模和参数数量4 GPT和文心一言的语言理解表现5 展望GPT和文心一言未来的发展5.1 技术改进5.2 应用扩展 结语 前言 随着人工智能技术的飞速发展&#xff0c;自然语言处理领域的两个引领…

linux报错bash: ./configure:/bin/sh^M:

bash: ./configure&#xff1a;/bin/sh^M&#xff1a;解释器错误: 没有那个文件或目录 用cat -A urfile时你可以看到这个\r字符被显示为^M&#xff0c;这时候只需要删除这个字符就可以了。可以使用命令sed -i s/\r$// urfile 。

swing快速入门(四十四)拖动、编辑JTree结点

注释很详细&#xff0c;直接上代码 新增内容&#xff08;源码细节知识点巨多&#xff0c;建议细看&#xff09; 1.设置JTree可编辑 2.使用JTree关联的数据模型实现节点的增删改 3.鼠标拖动节点事件设计及处理方法 4.手动刷新视图与自动刷新的方法区别 5.自定位节点视图方法 源码…

linux环境中一次启动多个jar包,并且设置脚本开机自启

1、编写启动脚本 我们在通过jar启动项目时&#xff0c;有时候会比较多&#xff0c;启动会比较麻烦&#xff0c;需要编写shell脚本启动&#xff0c;将启动脚本存放在需要启动的jar包路径下。&#xff08;文档存放在 /home/process_parent &#xff09; vim start.sh#! /bin/sh…

【python】11.文件和异常

文件和异常 实际开发中常常会遇到对数据进行持久化操作的场景&#xff0c;而实现数据持久化最直接简单的方式就是将数据保存到文件中。说到“文件”这个词&#xff0c;可能需要先科普一下关于文件系统的知识&#xff0c;但是这里我们并不浪费笔墨介绍这个概念&#xff0c;请大…

动态规划算法的应用

动态规划算法的应用 LeetCode&#xff1a;一只青蛙一次可以跳上1级台阶&#xff0c;也可以跳上2级台阶。求该青蛙跳上一个 10 级的台阶总共有多少种跳法。 思考&#xff1a; /*** 一只青蛙一次可以跳上1级台阶&#xff0c;也可以跳上2级台阶。求该青蛙跳上一个 10 级的台阶总…

为什么会被诊断为发作性睡病?

发作性睡病的诊断主要基于患者的症状和相关医学检查的结果。具体来说&#xff0c;医生会根据患者是否出现白天发作性嗜睡、猝倒、睡眠瘫痪和入睡前幻觉等症状来做出初步诊断。这些症状可能在不同的患者身上表现程度不同&#xff0c;但它们通常是发作性睡病的典型特征。 为了进…

Vue报错 Cannot find module ‘../../modules/es6.symbol‘解决办法

在进行webpack打包的时候&#xff0c;会出现Cannot find module XXX’的错误&#xff0c;找不到某个模块的错误&#xff0c;今天给出解决方法&#xff1a; 直接进行npm install重新打包&#xff1b;如果npm install重新打包之后&#xff0c;仍然出现这个问题&#xff0c;可以进…