spring源码分析——事务的实现原理

在对数据库进行操作时,有时候会把多个操作放到一个事务里,保证原子性,那么这个事务是怎么实现的呢?

下面我们先通过一个demo看一下事务的使用:

一:事务的使用

数据库jdbc配置:

java;gutter:true;</p> <h2>数据源配置</h2> <p>jdbc.driverClass=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://127.0.0.1:3306/study jdbc.username=root jdbc.password=root</p> <pre><code> spring-context.xml配置: 写一个类,方法上加上@Transactional注解 ;gutter:true;
@Service
public class TestTransactionalService {

@Autowired
private UserMapper userMapper;

@Transactional
public int add(){
User user = new User();
user.setName("Lucy");
user.setAge("30");
int effectCount = userMapper.insert(user);
System.out.println("影响条数: "+effectCount);
int i = 10/0;
return effectCount;
}

}

测试代码:

spring源码分析——事务的实现原理

spring源码分析——事务的实现原理

二:事务的原理分析

1:注册埋点,注册BeanDefinition对象,实例化BeanPostProcessor对象,并注册到beanPostProcessors中

配置开启事务管理:

spring源码分析——事务的实现原理

通过命名空间找到对象的handler类:

spring源码分析——事务的实现原理

注册自定义标签tx的属性解析器,AnnotationDrivenBeanDefinitionParser

spring源码分析——事务的实现原理

spring源码分析——事务的实现原理

spring源码分析——事务的实现原理

spring源码分析——事务的实现原理

spring源码分析——事务的实现原理

spring源码分析——事务的实现原理

spring源码分析——事务的实现原理

AutoProxyCreator已经以BeanDefinition的形式注册到了BeanDefinitionMaps中。

注册其他类:

spring源码分析——事务的实现原理

spring源码分析——事务的实现原理

spring源码分析——事务的实现原理

2:实例化并注册到beanPostProcessors中

是在refresh方法的registryBeanPostProcessor中实现的,这里不再赘述

3:寻找增强,创建代理

spring源码分析——事务的实现原理

spring源码分析——事务的实现原理

spring源码分析——事务的实现原理

spring源码分析——事务的实现原理

spring源码分析——事务的实现原理

spring源码分析——事务的实现原理

用增强去匹配当前bean信息:

spring源码分析——事务的实现原理

spring源码分析——事务的实现原理

spring源码分析——事务的实现原理

spring源码分析——事务的实现原理

spring源码分析——事务的实现原理

spring源码分析——事务的实现原理

创建代理:

spring源码分析——事务的实现原理

4:拦截方法,对方法进行增强

spring源码分析——事务的实现原理

TestTransactionalService这个对象已经被代理

进入DynamicAdvisedInterceptor类的intercept方法:

spring源码分析——事务的实现原理

只有一个增强:

spring源码分析——事务的实现原理

TransactionInterceptor 的 invoke方法

spring源码分析——事务的实现原理

spring源码分析——事务的实现原理

抛出异常,进入catch代码块:

spring源码分析——事务的实现原理

回滚事务:

spring源码分析——事务的实现原理

spring源码分析——事务的实现原理

spring源码分析——事务的实现原理

DataSourceTransactionManager类的doRollback回滚方法:

spring源码分析——事务的实现原理

可以看出正在执行回滚操作是在DataSourceTransactionManager类中进行的

spring源码分析——事务的实现原理

下面把导致异常的代码去掉,看一下提交的情况:

spring源码分析——事务的实现原理

提交事务:

spring源码分析——事务的实现原理

spring源码分析——事务的实现原理

spring源码分析——事务的实现原理

spring源码分析——事务的实现原理

调到了DataSourceTransactionManager的doCommit事务:

spring源码分析——事务的实现原理

到这里事务管理的分析就结束了,实现原理就是对数据库的操作方法进行增强,如果执行成功就commit,执行失败就rollback。

a: 看一下异常回滚里面小细节:rollbackFor ,什么异常才回滚?

spring源码分析——事务的实现原理

如果@Transactional注解上不配置rollbackFor 默认是RuntimException 或者 Error

spring源码分析——事务的实现原理

如果自定义rollbackFor类型:

spring源码分析——事务的实现原理

b:如果@Transactional注释的方法不是public修饰的,也不会被代理,找不到@Transactional注解的信息

spring源码分析——事务的实现原理

spring源码分析——事务的实现原理

c:如果是内部调用,会不会生效,从其他类调用add方法:

spring源码分析——事务的实现原理

调用add方法,进入intercept

spring源码分析——事务的实现原理

spring源码分析——事务的实现原理

在add方法中调用addData,实际是调用target的方法,不是代理方法,所以不会有事务的存在

spring源码分析——事务的实现原理

Original: https://www.cnblogs.com/warrior4236/p/13257450.html
Author: warrior1234
Title: spring源码分析——事务的实现原理

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/541596/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Java基础 while 简单示例

    JDK :OpenJDK-11 OS :CentOS 7.6.1810 IDE :Eclipse 2019‑03 typesetting :Markdown code packag…

    Java 2023年5月29日
    0105
  • 编译原理的文法和语言总结与梳理

    梳理文法和语言的内容,理解与总结。 我们都知道,一种语言必定他的文法去描述,它的完整定义包括语法和语义两个方面。语言和语法是指一组规则,用它可以形成和产生一个合适的程序。目前广泛使…

    Java 2023年6月7日
    093
  • 企业DevOps之路:Jenkins 流水线

    Pipeline 概述 Pipeline 即流水线,是 jenkins2.X 的新特性,是 jenkins 官方推荐使用的持续集成方案。与传统的自由风格项目不同,它是通过 jenk…

    Java 2023年6月7日
    098
  • spring中@Scheduled定时任务执行时间不准确问题

    一、问题背景 使用@Scheduled创建两个定时任务,其中一个1s执行。另一个1min执行。按分钟执行的出现了bug,我设定的规则如下: java;gutter:true; @A…

    Java 2023年5月30日
    083
  • Java bean与xml 互转(对象转xml、xml转对象)

    日常吐槽: 好久都没怎么分享自已了…… ╮(╯▽╰)╭,最近有个需求,需要把 bean对象 转成 xml 文件,然后 xml 文件 转成对象 ( 生成 与 …

    Java 2023年5月29日
    0103
  • springboot mvn install Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources

    错误信息: [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0…

    Java 2023年5月30日
    099
  • DOM

    DOM 所谓DOM是给文档中的每一个标签都对应的创建一个对象。 在JS中默认就会为页面的所有的标签创建一个对应的对象模型。我们可以通过对应的API获取这些对象模型,通过这些对象模型…

    Java 2023年6月7日
    089
  • Java源码赏析(五)再识 String 类

    在 Java源码赏析(三)初识 String 类 中,我们已经大概理解了String的接口,接下来我们描述一下String的常用工具方法。 /** * 为&#x4E8…

    Java 2023年6月8日
    066
  • Linux常用指令

    运行级别 运行级别说明:0 :关机1 :单用户【找回丢失密码】2:多用户状态没有网络服务3:多用户状态有网络服务4:系统未使用保留给用户5:图形界面6:系统重启常用运行级别是3 和…

    Java 2023年6月5日
    096
  • Java学习-086-Springboot 自定义启动 banner 信息

    Springboot 启动时会加载默认的 banner 信息,并在控制台输出。因而可以通过自定义 banner 文件内容实现启动 banner 的自定义。 在项目的 resouce…

    Java 2023年5月29日
    087
  • 【LEETCODE】70、字符匹配1023 Camelcase Matching

    最近做leetcode总感觉自己是个智障,基本很少有题能自己独立做出来,都是百度。。。 不过终于还是做出了一题。。。而且速度效率还可以 哎,加油吧,尽量锤炼自己 package y…

    Java 2023年6月5日
    065
  • springboot集成webservice,基于用户名,密码

    springboot集成webservice,基于用户名,密码 https://blog.csdn.net/hsqingwei/article/details/89331959 p…

    Java 2023年5月30日
    084
  • Spring JDBC操作

    1、在JAVA创建数据库表对象 2、创建DAO接口及其对应实现类 3、创建sevice 4、编辑XML配置 5、批量操作 Original: https://www.cnblogs…

    Java 2023年6月7日
    077
  • 我是一个垃圾

    哒哒哒…… 回收者的脚步声越来越清晰,我竭力锁紧身体让自己别那么引人注目,尽管气喘吁吁,但我仍然压抑住自己的呼吸。 终归是藏不住的,但是多活个几毫秒也是好的…

    Java 2023年6月7日
    064
  • hdu 1385 Minimum Transport Cost (floyd算法)

    貌似···················· 这个算法深的东西还是很不熟悉!继续学习!!!! ++++++++++++++++++++++++++++ ==============…

    Java 2023年5月29日
    077
  • Springcloud aliBaBa+k8s+hadoop 20220803笔记本12

    项目并发量(线程) 1、线程数(Web服务)=>单tomcat:250>数量>150 集tomcat:>500 2、线程数(系统进程)=>Window…

    Java 2023年5月30日
    0101
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球