总文档 :文章目录
Github : github.com/black-ant
一 . 前言
这一篇讲事务管理相关的流程 , 以 SpringDataJPA 为例.
文章的目的 :
- 梳理 Spring Transaction 的主流程
- 说明 Spring Transaction 的核心原理
- 流程中的参数传递
一句话原理 :
- 通过 SQL START TRANSACTION; + COMMIT; 实现数据库级的事务管理
- 通过 代理的方式进行整体的管控 , 通过代理类开启 START TRANSACTION
- 通过 Mysql rollback 事务回滚
主流程 :
- TransactionManager
- JpaTransactionManager
- PlatformTransactionManager
二 . 事务处理流程
事务管理的核心是对象 TransactionManager , 我们来看一下他的家族体系 :
大概可以看到 , 主要的实现类有 :
1 | java复制代码C- DataSourceTransactionManager |
2.1 事务的拦截入口
事务的起点是通过 Interceptor 进行拦截的 , 其代理方式也是通过 AOP 实现的 ,其入口类为 CglibAopProxy
1 | java复制代码C01- TransactionInterceptor |
PS:001 TransactionAspectSupport 的作用
类的作用 : 事务基础类 , 子类负责以正确的顺序调用该类中的方法
特点 : 基于 策略模式 设计
2.2 流程的拦截
- Step 1 : 属性准备
- TransactionAttributeSource : TransactionInterceptor用于元数据检索的策略接口
- TransactionAttribute : 该接口将rollbackOn规范添加到TransactionDefinition。
- PlatformTransactionManager : 事务管理平台
- joinpointIdentification
- Step 2 : 分为 2 种类型处理
- 存在用于在事务中执行给定回调的方法
- 不存在回调方法
1 | java复制代码C02- TransactionAspectSupport |
参数详情
这里看一看相关的参数详情
M02_01 源代码
1 | java复制代码 protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass, |
3.3 流程的处理
如何调用到该方法 :
- TransactionAspectSupport # invokeWithinTransaction
- TransactionAspectSupport # createTransactionIfNecessary
- AbstractPlatformTransactionManager # getTransaction
M02_02 源代码 , 先来看一下第二步怎么到 getTransaction 的
1 | java复制代码 |
可以看到 , 相关代码为 status = tm.getTransaction(txAttr)
TransactionManager 总共有2个 :
- AbstractPlatformTransactionManager : 总的抽象事务管理器
- JpaTransactionManager : 因为是基于 JPA , 此处是 JpaTransactionManager
1 | java复制代码C03- AbstractPlatformTransactionManager |
PS:M03_01_01 newTransactionStatus
作用 : 用给定的参数创建一个TransactionStatus实例
1 | java复制代码protected DefaultTransactionStatus newTransactionStatus(TransactionDefinition definition, @Nullable Object transaction, boolean newTransaction,boolean newSynchronization, boolean debug, @Nullable Object suspendedResources) { |
S:M03_01_02 具体的流程
作用 : 根据给定的事务定义,使用语义开始一个新的事务 。 由于已经由抽象管理器处理过 , 所以不需要关心传播行为的应用。当事务管理器决定实际启动一个新事务时,将调用此方法。要么之前没有任何交易,要么之前的交易已经暂停。
S:M02_05_01 中干了什么 ?
txInfo.getTransactionManager().commit(txInfo.getTransactionStatus())
可以看到 , 这里通过 TransactionManager 调用具体的 Commit -> AbstractPlatformTransactionManager
1 | java复制代码C03- AbstractPlatformTransactionManager |
3.5 异常的处理
异常的处理主要是回退的相关操作 , 该操作主要在 C03- AbstractPlatformTransactionManager 中
Rollback 的调用 :
观察发现 , Rollback 不仅仅在出现异常时调用 , 这里会有不同的场景 , 主要的有2种 type :
- 事务代码请求回滚 :
processRollback(defStatus, false)
- 全局事务被标记为仅回滚但请求提交事务代码 :
processRollback(defStatus, true)
1 | java复制代码// 事务的回退主流程 |
PS:M04_03_01 参数详情
JpaTransactionObject 参数详情
这里可以看到 , 每一个操作都会形成一个 EntityInsertAction
PS:M05_01_03 回退逻辑详情
核心类为 JdbcResourceLocalTransactionCoordinatorImpl , 回退有如下调用栈 (中间有部分省略) :
setAutoCommit 环节
- JpaTransactionManager # doBegin
- HibernateJpaDialect # beginTransaction
- TransactionImpl # begin
- JdbcResourceLocalTransactionCoordinatorImpl # begin
- HikariProxyConnection # setAutoCommit
- ConnectionImpl # setAutoCommit
- NativeProtocol # sendQueryString
SQL 执行环节
- HikariProxyPreparedStatement # executeQuery
- NativeSession # execSQL
- NativeProtocol # sendQueryString
PS :最终执行语句均为 :
- NativeProtocol # sendQueryString
1 | java复制代码C11- JdbcResourceLocalTransactionCoordinatorImpl |
总结
整体大概是把 JPA Transaction 的流程过了一遍 , 不过一直有一点怀疑 , 现阶段看出来的就是通过 SQL 其本身的事务管理来做的 , 不确定是否有其他的环节控制或者通过业务的方式处理 .
附录
Mysql 事务回滚机制
1 | java复制代码官方文档 @ https://dev.mysql.com/doc/refman/8.0/en/innodb-autocommit-commit-rollback.html |
先来看一下 , 官方提供的案例 :
在 InnoDB 中,所有的用户活动都发生在一个事务中。如果启用了自动提交模式,则每个 SQL 语句自己形成一个事务。
注意 , 在 MyMyISAM 中 ,这种处理是失效的!!
1 | SQL复制代码CREATE TABLE customer (a INT, b CHAR (20), INDEX (a)); |
类型一 : 多语句事务提交
- 如果这里不执行 commit , 当前操作是不会提交的
1 | SQL复制代码 |
类型二 :回退操作
1 | SQL复制代码# Step 1 : 设置非自动提交 |
对于本案例的事务处理
1 | sql复制代码START TRANSACTION; |
观察到的本案例的 SQL 操作
1 | sql复制代码# 项目启动时 |
PS : 这里可以 Debug C- NativeProtocol # sendQueryString 拿到
M04_01 : JpaTransactionManager # doGetTransaction()源码
1 | java复制代码protected Object doGetTransaction() { |
M04_02 : JpaTransactionManager # doBegin()源码
1 | java复制代码protected void doBegin(Object transaction, TransactionDefinition definition) { |
本文转载自: 掘金