牛皮,你竟然徒手写出来了Spring事务的核心代码!

Posted Java面试那些事儿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛皮,你竟然徒手写出来了Spring事务的核心代码!相关的知识,希望对你有一定的参考价值。

# 前言


事务,是描述一组操作的抽象,比如对数据库的一组操作,要么全部成功,要么全部失败。事务具有4个特性:Atomicity(原子性),Consistency(一致性),Isolation(隔离性),Durability(持久性)。在实际开发中,我们对事务应用最多就是在数据库操作这一环,特别是Spring对数据库事务进行了封装管理。


Spring对事务的支持,确实很强大,但是从本质上来讲:事务是否生效取决数据库底层是否支持(比如MySQL的MyISAM引擎就不支持事务,Spring能奈何!),同时一个事务的多个操作需要在同一个Connection上。事务也往往是在业务逻辑层来控制。本篇博客将通过手写一个Demo来分析Spring事务底层到底是如何帮助我们轻松完成事务管理的!


# 透彻理解Spring事务设计思想之手写实现


先来看一眼工程结构:


牛皮,你竟然徒手写出来了Spring事务的核心代码!


ConnectionHolder


牛皮,你竟然徒手写出来了Spring事务的核心代码!


在Spring中,有时候我们是不是要配置多个数据源DataSource?很显然,Spring需要通过DataSource来得到操作数据库的管道Connection,这有点类似于JNDI查找。


这里通过ConnectionHolder类来完成这个过程,需要思考的是在多线程下,这显然是存在问题的。为避免多线程问题,难道我们采用线程安全的Map,比如ConcurrentHashMap,其实我们真正的目的是什么?是保证一个线程下,一个事务的多个操作拿到的是一个Connection,显然使用ConcurrentHashMap根本无法保证!


Spring很聪明,她提供了一种思路,来解决,看下面的代码!


SingleThreadConnectionHolder


牛皮,你竟然徒手写出来了Spring事务的核心代码!


本来线程不安全的,通过ThreadLocal这么封装一下,立刻就变成了线程的局部变量,不仅仅安全了,还保证了一个线程下面的操作拿到的Connection是同一个对象!这种思想,确实非常巧妙,这也是无锁编程思想的一种方式!


TransactionManager


牛皮,你竟然徒手写出来了Spring事务的核心代码!


TransactionManager,这个我们经常在Spring里面进行配置吧,事务大管家!


UserAccountDao、UserOrderDao


牛皮,你竟然徒手写出来了Spring事务的核心代码!


牛皮,你竟然徒手写出来了Spring事务的核心代码!


这里通过这2个DAO,想模拟一个事务中账户购买、下单2个操作。


UserService


牛皮,你竟然徒手写出来了Spring事务的核心代码!


到这里,可以清晰的看到Spring事务管理的一个缩影了吧!


Test


牛皮,你竟然徒手写出来了Spring事务的核心代码!


这里,主要是模拟Spring的注入以及多用户并发请求。


运行结果


牛皮,你竟然徒手写出来了Spring事务的核心代码!


你可以发现,一个线程中的一个事务的多个操作,使用的是同一个Connection!


作者:张丰哲
链接:https://www.jianshu.com/p/1becdc376f5d



 往期推荐 

以上是关于牛皮,你竟然徒手写出来了Spring事务的核心代码!的主要内容,如果未能解决你的问题,请参考以下文章

手写Spring事务框架

利用反射手写代码实现spring AOP

What?天天用Spring你竟然不知道事务的传播性?

1000行代码徒手写正则表达式引擎--JAVA中正则表达式的使用

牛皮啊!竟然可以为Dubbo接口生成文档了!

30个类手写Spring核心原理之AOP代码织入