第二十七章 Spring之假如让你来写事务——铁三角篇

Spring源码阅读目录

第一部分——IOC篇

第一章 Spring之最熟悉的陌生人——IOC
第二章 Spring之假如让你来写IOC容器——加载资源篇
第三章 Spring之假如让你来写IOC容器——解析配置文件篇
第四章 Spring之假如让你来写IOC容器——XML配置文件篇
第五章 Spring之假如让你来写IOC容器——BeanFactory和FactoryBean
第六章 Spring之假如让你来写IOC容器——Scope和属性填充
第七章 Spring之假如让你来写IOC容器——属性填充特别篇:SpEL表达式
第八章 Spring之假如让你来写IOC容器——拓展篇
第九章 Spring之源码阅读——环境搭建篇
第十章 Spring之源码阅读——IOC篇

第二部分——AOP篇

第十一章 Spring之不太熟的熟人——AOP
第十二章 Spring之不得不了解的内容——概念篇
第十三章 Spring之假如让你来写AOP——AOP联盟篇
第十四章 Spring之假如让你来写AOP——雏形篇
第十五章 Spring之假如让你来写AOP——Joinpoint(连接点)篇
第十六章 Spring之假如让你来写AOP——Pointcut(切点)篇
第十七章 Spring之假如让你来写AOP——Advice(通知)上篇
第十八章 Spring之假如让你来写AOP——Advice(通知)下篇
第十九章 Spring之假如让你来写AOP——番外篇:Spring早期设计
第二十章 Spring之假如让你来写AOP——Aspect(切面)篇
第二十一章 Spring之假如让你来写AOP——Weaver(织入器)篇
第二十二章 Spring之假如让你来写AOP——Target Object(目标对象)篇
第二十三章 Spring之假如让你来写AOP——融入IOC容器篇
第二十四章 Spring之源码阅读——AOP篇

第三部分——事务篇

第二十五章 Spring之曾经的老朋友——事务
第二十六章 Spring之假如让你来写事务——初稿篇
第二十七章 Spring之假如让你来写事务——铁三角篇
第二十八章 Spring之假如让你来写事务——属性篇
第二十九章 Spring之假如让你来写事务——状态篇
第三十章 Spring之假如让你来写事务——管理篇
第三十一章 Spring之假如让你来写事务——融入IOC容器篇
第三十二章 Spring之源码阅读——事务篇

第四部分——MVC篇

第三十三章 Spring之梦开始的地方——MVC
第三十四章 Spring之假如让你来写MVC——草图篇
第三十五章 Spring之假如让你来写MVC——映射器篇
第三十六章 Spring之假如让你来写MVC——拦截器篇
第三十七章 Spring之假如让你来写MVC——控制器篇
第三十八章 Spring之假如让你来写MVC——适配器篇
第三十九章 Spring之假如让你来写MVC——番外篇:类型转换
第四十章 Spring之假如让你来写MVC——ModelAndView篇
第四十一章 Spring之假如让你来写MVC——番外篇:数据绑定
第四十二章 Spring之假如让你来写MVC——视图篇
第四十三章 Spring之假如让你来写MVC——上传文件篇
第四十四章 Spring之假如让你来写MVC——异常处理器篇
第四十五章 Spring之假如让你来写MVC——国际化篇
第四十六章 Spring之假如让你来写MVC——主题解析器篇
第四十七章 Spring之假如让你来写MVC——闪存管理器篇
第四十八章 Spring之假如让你来写MVC——请求映射视图篇
第四十九章 Spring之假如让你来写MVC——番外篇:属性操作
第五十章 Spring之假如让你来写MVC——融入IOC容器篇
第五十一章 Spring之源码阅读——MVC篇

第五部分——Boot篇

第五十二章 Spring之再进一步——Boot
第五十三章 Spring之假如让你来写Boot——环境篇
第五十四章 Spring之假如让你来写Boot——注解篇(上)
第五十五章 Spring之假如让你来写Boot——注解篇(下)
第五十六章 Spring之假如让你来写Boot——SPI篇
第五十七章 Spring之假如让你来写Boot——配置文件篇(上)
第五十八章 Spring之假如让你来写Boot——配置文件篇(下)
第五十九章 Spring之假如让你来写Boot——番外篇:再谈Bean定义
第六十章 Spring之假如让你来写Boot——自动装配篇
第六十一章 Spring之假如让你来写Boot——番外篇:杂谈Starter
第六十二章 Spring之假如让你来写Boot——番外篇:重构BeanFactory
第六十三章 Spring之假如让你来写Boot——番外篇:再谈ApplicationContext
第六十四章 Spring之假如让你来写Boot——内嵌Web容器篇
第六十五章 Spring之假如让你来写Boot——Main方法启动篇
第六十六章 Spring之最终章——结语篇



前言

    对于Spring一直都是既熟悉又陌生,说对它熟悉吧,平时用用没啥问题,但面试的时候被问的一脸懵逼,就很尴尬,都不好意思在简历上写着熟悉Spring了
在这里插入图片描述

    所以决定花点时间研究研究Spring的源码。主要参考的书籍是:《Spring源码深度解析(第2版)》、《Spring揭秘》、《Spring技术内幕:深入解析Spring架构与设计原理(第2版)》


    书接上回,在上篇 第二十六章 Spring之假如让你来写事务——初稿篇 中,A君 简单的实现了 事务,好向老大交差。接下来看看 A君 会有什么骚操作吧

尝试动手写IOC容器

    出场人物:A君(苦逼的开发)、老大(项目经理)

    背景:老大要求A君在一周内开发个简单的 IOC容器

    前情提要: A君 简单的实现了 事务,好向老大交差 。。。

第二十五版 事务铁三角

    “ A君,你还真是个天才啊!” 老大 看着 A君 提交上来的代码,哭笑不得

    面对 老大 的阴阳,A君 一阵无奈,这么短的时间,让人怎么细细考虑设计嘛

    “说说看,你之后打算如何优化。” 老大 继续说到

    显然,老大 对这个版本并不满意,不过也透漏出会给 A君 一点的时间进行改造。A君 仔细了思索片刻,回答道:“事务 存在着很多属性,比如说:超时时间、隔离级别、是否只读等属性,这部分内容可以提取出来。”

    “是的,但是不单单是 事务 本身的属性,我们还可以添加一些传播行为,还满足不同场景下的需求,例如说:嵌套事务。还得根据不同异常来控制是否回滚。” 老大 说完,顿了下,继续说道:“除了 事务属性,你还能想到哪些东西?”

    “没,除了这些,想不出其他东西。” A君 思考了一阵,决定放弃思考,这玩意实在不懂,听听 老大 怎么说吧

    “除了 事务属性 之外,应该还有 事务状态。我们需要根据 事务状态 来进行相应的处理。还有一点是,在 JDBC 3.0 新增了 SAVEPOINT ,这个可以是 事务 中设置保存点,这样 事务 回滚的时候,可以回滚到对应的保存点,而不是整个 事务。” 老大 似乎来了兴致了,侃侃而谈,并没有停下来的意思。继续说道:“还有一个点,我们需要对 事务 进行同一个管理,而不是纠结于具体的实现,在你提交上来的代码中,只能支持 JDBC 访问数据库的形式,如果后面要对接 HibernateMybatis 呢?甚至是 JMSJTA 呢?” 老大 停下了喝了口水,又道:“事务属性事务属性事务管理器 组成了整个 事务 的铁三角,完成了整个 事务 的实现。那先这样吧,你回去好好想下怎么实现吧!”

    “好的。” A君 默默的回到自己的工位。其实,别看 老大 说的那么高档大气,对于 A君 来说,都是接口罢了。A君 决定先把接口定义出来,后续再去考虑具体实现。A君 先定义一个 TransactionDefinition 接口,作为 事务属性 的顶级接口。代码如下:

/**
 * 事务属性接口,定义事务相关属性
 */
public interface TransactionDefinition {
    int PROPAGATION_REQUIRED = 0;

    int PROPAGATION_SUPPORTS = 1;

    int PROPAGATION_MANDATORY = 2;

    int PROPAGATION_REQUIRES_NEW = 3;

    int PROPAGATION_NOT_SUPPORTED = 4;

    int PROPAGATION_NEVER = 5;

    int PROPAGATION_NESTED = 6;

    int ISOLATION_DEFAULT = -1;

    int ISOLATION_READ_UNCOMMITTED = 1;  // 等价于 java.sql.Connection.TRANSACTION_READ_UNCOMMITTED;

    int ISOLATION_READ_COMMITTED = 2;  // 等价于 java.sql.Connection.TRANSACTION_READ_COMMITTED;

    int ISOLATION_REPEATABLE_READ = 4;  // 等价于 java.sql.Connection.TRANSACTION_REPEATABLE_READ;

    int ISOLATION_SERIALIZABLE = 8;  // 等价于java.sql.Connection.TRANSACTION_SERIALIZABLE;

    int TIMEOUT_DEFAULT = -1;

    static TransactionDefinition withDefaults() {
        return StaticTransactionDefinition.INSTANCE;
    }

    default int getPropagationBehavior() {
        return PROPAGATION_REQUIRED;
    }

    default int getIsolationLevel() {
        return ISOLATION_DEFAULT;
    }

    default int getTimeout() {
        return TIMEOUT_DEFAULT;
    }

    default boolean isReadOnly() {
        return false;
    }


    default String getName() {
        return null;
    }
}

再定义个 TransactionAttribute 接口,作为其子接口。代码如下:

import com.hqd.ch03.v25.tx.transaction.TransactionDefinition;

public interface TransactionAttribute extends TransactionDefinition {
    boolean rollbackOn(Throwable ex);
}

    再来就是 事务状态 了,按 老大 的说法,事务状态 不止包含了 事务 运行状态,还有 SAVEPOINT 相关操作,按 单一性原则,得拆成两个接口。想到这里,A君 定义 TransactionExecution 接口,作为 事务 运行状态的顶级接口。代码如下:

/**
 * 事务执行状态
 */
public interface TransactionExecution {
    /**
     * 是否新事务
     *
     * @return
     */
    boolean isNewTransaction();

    /**
     * 设置事务只读
     */
    void setRollbackOnly();

    /**
     * 是否只读事务
     *
     * @return
     */
    boolean isRollbackOnly();

    /**
     * 事务是否已完成
     *
     * @return
     */
    boolean isCompleted();
}

接着就是 SAVEPOINT 相关操作的接口,A君 定义 SavepointManager 接口。代码如下:

/**
 * 保存点管理接口
 */
public interface SavepointManager {
    /**
     * 创建保存点
     *
     * @return
     */
    Object createSavepoint();

    /**
     * 回滚到对应的保存点
     *
     * @param savepoint
     */
    void rollbackToSavepoint(Object savepoint);

    /**
     * 释放保存点
     *
     * @param savepoint
     */
    void releaseSavepoint(Object savepoint);
}

事务状态 接口其实就是这两个接口的结合体,A君 定义 TransactionStatus 作为 事务状态 的最终接口,代码如下:

import java.io.Flushable;

public interface TransactionStatus extends TransactionExecution, SavepointManager, Flushable {
    /**
     * ‘
     * 是否存在保存点
     *
     * @return
     */
    boolean hasSavepoint();

    @Override
    void flush();
}

    最后一个就是 事务管理器 了,说是 事务管理器,无非就是根据 事务状态 进行提交或回滚操作罢了,接口本身并不是很复杂。于是,A君 定义 PlatformTransactionManager 接口,代码如下:

/**
 * 事务管理器
 */
public interface PlatformTransactionManager extends TransactionManager {
    /**
     * 获取事务状态
     *
     * @param definition
     * @return
     */
    TransactionStatus getTransaction(TransactionDefinition definition);

    /**
     * 提交事务
     *
     * @param status
     */
    void commit(TransactionStatus status);

    /**
     * 回滚事务
     *
     * @param status
     */
    void rollback(TransactionStatus status);
}

    好了,‘三剑客’ 都定义完毕了,都是接口也没有什么测试的必要了。今天就先到这里了。A君 准备溜了,下班不积极,脑袋有问题

在这里插入图片描述


总结

    正所谓树欲静而风不止,欲知后事如何,请看下回分解(✪ω✪)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

穷儒公羊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值