当前位置: 首页 > article >正文

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

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

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


01

Spring 事务概述

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

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

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 的帮助下,我们只需要一行注解,就很优雅。

@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技术内幕》(四)事务

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

文章推荐:

  • 如何提高核心竞争力
  • 读书笔记-《当下的力量》
  • 读书笔记-《写给大家看的设计书》
  • 赛博朋克2077玩后感
  • 程序员工作中常见问题,你遇到过几个?
  • 如何设计离线跑批系统
  • 读书笔记-《人人都是产品经理》
  • 如何养成好习惯
  • 读书笔记-《最好的告别》


http://www.kler.cn/a/379164.html

相关文章:

  • LeetCode //C - 447. Number of Boomerangs
  • 【AIGC】如何充分利用ChatGPT:有效提示框架与基本规则
  • 对象池模式
  • 人脑与机器连接:神经科技的伦理边界探讨
  • 看门狗有什么用?
  • 软件测试面试八股文个人总结
  • 【亚马逊云】基于 AWS 使用CloudFormation快速部署 VMClarity 环境
  • celery在django项目中实现并发任务和定时任务
  • SOLIDWORKS 2025用户体验新功能
  • NineData云原生智能数据管理平台新功能发布|2024年10月版
  • distrobox install in ubuntu 22.04 / 在 ubuntu 22.04 上安装 distrobox (***) OK
  • qt的c++环境配置和c++基础【正点原子】嵌入式Qt5 C++开发视频
  • Stable Diffusion Web UI 1.9.4常用插件扩展-WD14-tagger
  • Spring Boot技术:校园社团信息管理的创新解决方案
  • 123.WEB渗透测试-信息收集-ARL(14)
  • 初始计算机网络
  • sqlserver、达梦、mysql的差异
  • React 组件生命周期与 Hooks 简明指南
  • HTTP代理是什么?有什么用?
  • git pull遇到一个问题
  • 揭秘Scam-as-a-Service:警惕钓鱼攻击的产业化
  • centos7之LVS-DR模式传统部署
  • 21 Docker容器集群网络架构:四、Docker集群网络验证
  • 在k8s环境中如何在本地和pod之间同步文件?
  • 基于微信小程序的生签到系统设计与实现(lw+演示+源码+运行)
  • 一键式配置适合 Web 开发的Ubuntu系统