读书笔记-《Spring技术内幕》(四)事务

前面我们依次学习了 IoC、AOP、MVC(读书笔记-《Spring技术内幕》(一)IoC容器的实现读书笔记-《Spring技术内幕》(二)AOP的实现读书笔记-《Spring技术内幕》(三)MVC与Web环境),已经涵盖了 Spring 最核心的内容。

今天,我们再来研究一个比较常用的组件------事务,然后这本书的读书笔记就可以完结了~


01

Spring 事务概述

按照惯例,我们先从程序员的视角出发,看看 Spring 帮我们做了什么,再学习其具体的设计与实现。

在没有使用 Spring 的 JavaWeb 项目中,是怎么实现事务的呢?请看下面的示例代码:

java 复制代码
public void hello {
    Connection conn = openConnection();
    try {
        conn.setAutoCommit(false);
        // 业务代码
        conn.commit();
    } catch (SQLException e) {
        conn.rollback();
    } finally {
        conn.setAutoCommit(true);
        conn.close();
    }
}

这个 Connection 我印象很深,初学时因为它学习到了第一个设计模式------单例模式,这个模式的懒汉/饿汉实现、双重检测是早期常见的面试题。(跑题了,赶紧拉回来......)

简单来说,这里的代码直接操作数据库连接,并且将事务处理代码和业务代码耦合,非常糟糕。

而在 Spring 的帮助下,我们只需要一行注解,就很优雅。

java 复制代码
@Transactional
public void world {
    // 业务代码
}

看到这种将非业务功能代码解耦出来,并通过注解(声明式)实现功能的操作,很容易猜到,其原理是通过 AOP 将事务处理的功能编织进来,本质上可以看作是一个基于 Spring IoC、AOP 的优秀应用。 (注意:后面默认指代的是声明式使用,Spring 事务也可以编程式使用,其实现非常简单,不涉及框架特性,但是会耦合业务代码,本文不做讲述)

既然如此,从流程上看 Spring 事务的实现就有两个重点

  • 如何读取配置,并构造这个代理对象?

  • 这个代理对象如何实现事务的创建、提交、回滚等等?


02

Spring 事务设计概览

在回答上面两个问题之前,我们先看看类层次结构。

简单概括并补充一下:

  • ProxyConfig、FactoryBean 等:为前面 IoC、AOP 模块的设计,不做赘述。

  • **TransactionProxyFactoryBean:**生成代理对象。

  • **TransactionInterceptor:核心类,**对代理方法进行拦截,将事务功能编织进来。

  • **PlatformTransactionManager、AbstractPlatformTransactionManager:**封装底层不同数据库对事务的实现,如生成、提交、回滚、挂起等。

  • **TransactionAttribute:**事务配置信息在 Spring 中的抽象。

  • **TransactionInfo:**事务信息抽象,包含事务和 TransactionStatus。


    03

    构建代理对象

​​​​​​​​​​​​​​

​​​​​​​****

构建代理对象的时序图如上所示,用文字概括一下:

  • 在 IoC 容器完成 Bean 的依赖注入时,通过 initializeBean() 调用 createMainInterceptor(),创建一个 TransactionAttributePointcut,为读取 TransactionAttribute 做准备。

  • 由于 AbstractSingletonProxyFactoryBean 实现了 InitializingBean 接口,在 afterPropertiesSet() 中会实例化 ProxyFactory,设置通知、目标对象,最终返回代理对象。

  • 在构建好代理对象后,调用代理方法时便会调用相应的 TransactionInterceptor,匹配对应的配置。(举个例子的话可以看看 NameMatchTransactionAttributeSource,其通过成员变量 nameMap 的维护来实现名称匹配)


04

****处理事务

构建好代理对象后,对原方法的调用就会被拦截,也就是进入 TransactionInterceptor 的 invoke()。其会依次获取事务处理配置、PlatformTransactionManager,并交由这个具体的处理器来实现事务的创建、提交、回滚等等。

这里我们就以事务的创建为例,看看 TransactionAspectSupport 的 createTransactionIfNecessary 方法的时序图。

这里就两点可以留意下:

  • 针对不同的事务传播机制,源码里有各种条件分支。(不过在实际工作中,我还没使用过非默认的传播机制,一般是通过 MQ 来保障最终一致性)

  • bindToThread() 是通过 TransactionAspectSupport 的成员变量 ThreadLocal<TransactionInfo> transactionInfoHolder 实现,其也体现了事务的隔离性。

至此,我们只需再进一步就可抵达终点了。

前面的类层次结构图有提到 AbstractPlatformTransactionManager,其定义了事务的生成、提交、回滚、挂起,对于不同的数据库有不同的实现。

以 DataSourceTransactionManager 为例,点开它的源码一看,我们就会发现非常眼熟。它就和一开始我们写的示例代码类似,直接操作 Connection,打印日志等等。


​​​​​​​

原文链接读书笔记-《Spring技术内幕》(四)事务

原创不易,点个关注不迷路哟,谢谢~

文章推荐:

相关推荐
中屹指纹浏览器3 分钟前
2026高并发多账号运营下指纹浏览器性能调优与工程化实践
经验分享·笔记
青春易逝丶7 分钟前
策略模式
java·开发语言·策略模式
Amazing_Cacao8 分钟前
工艺师初级|参数与风味对齐(精品可可,精品巧克力)
笔记·学习
贼爱学习的小黄16 分钟前
NC BIP参照开发
java·前端·nc
小江的记录本20 分钟前
【MyBatis-Plus】MyBatis-Plus的核心特性、条件构造器、分页插件、乐观锁插件
java·前端·spring boot·后端·sql·tomcat·mybatis
小张会进步21 分钟前
数组:二维数组
java·javascript·算法
驕傲的兎孒28 分钟前
基于 SpringBoot + Vue3 + AI 打造企业级售后服务支持平台 | 实战方案分享
人工智能·spring boot·后端
vx-程序开发28 分钟前
springboot在线装修管理系统-计算机毕业设计源码56278
java·c语言·spring boot·python·spring·django·php
大傻^31 分钟前
Spring AI Alibaba 可观测性实践:AI应用监控与链路追踪
java·人工智能·后端·spring·springaialibaba