查看原文
其他

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

张丰哲 程序员小乐 2020-10-08

点击上方 "程序员小乐" ,关注公众号

8点20分,第一时间与你相约

每日英文 

Learn to stand for what you believe in no matter what people say. You live not to please everyone.

学着坚持自己认定的事,不要管别人怎么说,人活着,不是要取悦别人。

每日掏心话 

生活总是这样,不能叫人处处都满意。但我们还要热情地活下去。


来自:张丰哲 | 责编:乐乐

链接:jianshu.com/p/1becdc376f5d

图片来自网络



 00 前言  


事务,是描述一组操作的抽象,比如对数据库的一组操作,要么全部成功,要么全部失败。事务具有4个特性:Atomicity(原子性),Consistency(一致性),Isolation(隔离性),Durability(持久性)。在实际开发中,我们对事务应用最多就是在数据库操作这一环,特别是Spring对数据库事务进行了封装管理。Spring对事务的支持,确实很强大,但是从本质上来讲:事务是否生效取决数据库底层是否支持(比如MySQL的MyISAM引擎就不支持事务,Spring能奈何!),同时一个事务的多个操作需要在同一个Connection上。事务也往往是在业务逻辑层来控制。本篇博客将通过手写一个Demo来分析Spring事务底层到底是如何帮助我们轻松完成事务管理的!


 

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


先来看一眼工程结构:

工程结构

ConnectionHolder

ConnectionHolder

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

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

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

SingleThreadConnectionHolder

SingleThreadConnectionHolder

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

TransactionManager

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

UserAccountDao、UserOrderDao

UserAccountDao

UserOrderDao

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

UserService

UserService

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

Test

测试

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

运行结果

运行结果

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

好了,到这里,你是否能对Spring实现事务的思想有所了解呢?


谈谈你对Spring事务设计的理解?


欢迎在评论区留下你的观点,一起讨论提高。如果今天的文章让你有新的启发,或者在学习能力的提升上有新的认识,欢迎转发分享给更多人。


欢迎各位读者加入程序员小乐读者群,在公众号后台回复“加群”或者“学习”即可。


猜你还想看


阿里、腾讯、百度、华为、京东最新面试题汇集

常用的分布式事务解决方案介绍有多少种?

19个有趣的Linux 命令,最后一个?... 打死我都不敢尝试!

如何创作一篇优秀的技术文章?

图解排序算法(一):3种简单排序(选择、冒泡、直接插入)

SpringBoot 打包部署,看这篇就够了!

这里有技术心得算法职场感悟面经,做一个有趣的帮助程序员成长的公众号。

关注「程序员小乐」,收看更多精彩内容

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存