面试官:说说 Spring 事务设计原理?面试必问!

爱被打了一巴掌 2022-08-28 00:48 312阅读 0赞

点击上方“Java基基”,选择“设为星标”

做积极的人,而不是积极废人!

每天 14:00 更新文章,每天掉亿点点头发…

源码精品专栏

  • 原创 | Java 2021 超神之路,很肝~

  • 中文详细注释的开源项目

  • RPC 框架 Dubbo 源码解析

  • 网络应用框架 Netty 源码解析
  • 消息中间件 RocketMQ 源码解析

  • 数据库中间件 Sharding-JDBC 和 MyCAT 源码解析

  • 作业调度中间件 Elastic-Job 源码解析
  • 分布式事务中间件 TCC-Transaction 源码解析
  • Eureka 和 Hystrix 源码解析
  • Java 并发源码

来源:www.jianshu.com/
p/1becdc376f5d

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

00b128237138839b02d1604477813b8e.png


前言

事务,是描述一组操作的抽象,比如对数据库的一组操作,要么全部成功,要么全部失败。事务具有4个特性:Atomicity(原子性),Consistency(一致性),Isolation(隔离性),Durability(持久性)。

在实际开发中,我们对事务应用最多就是在数据库操作这一环,特别是Spring对数据库事务进行了封装管理。

Spring对事务的支持,确实很强大,但是从本质上来讲:事务是否生效取决数据库底层是否支持(比如MySQL的MyISAM引擎就不支持事务,Spring能奈何!),同时一个事务的多个操作需要在同一个Connection上。事务也往往是在业务逻辑层来控制。

本篇博客将通过手写一个Demo来分析Spring事务底层到底是如何帮助我们轻松完成事务管理的!

推荐下自己做的 Spring Boot 的实战项目:

https://github.com/YunaiV/ruoyi-vue-pro

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

先来看一眼工程结构:

0daa21b07a3bf1eba29dc59f8d144f8c.png 工程结构

ConnectionHolder

527908db7e9b8ed2e19ac63d4fa52d6f.png ConnectionHolder

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

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

Spring很聪明,她提供了一种思路,来解决,看下面的代码!另外,Spring 系列面试题和答案全部整理好了,微信搜索Java技术栈,在后台发送:面试,可以在线阅读。

SingleThreadConnectionHolder

a73500d0aa5af7d2baf1fe540338fdde.png SingleThreadConnectionHolder

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

TransactionManager

0b38bd7d77b477a6dd3fbd866bdc95b0.png TransactionManager

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

UserAccountDao、UserOrderDao

22da22331f1043da91d6803edbf4d678.png UserAccountDao 0e3d9a2fadbca1ab949a0fb6de1d99e7.png UserOrderDao

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

UserService

9877a49593473beee9e757de7f178b64.png UserService

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

Test

9a5cd5fe2f3a9d2bd7653317d047e3f3.png 测试

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

运行结果

1d2a6246834633060a1a7ac6e0ce3d07.png 运行结果

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

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



欢迎加入我的知识星球,一起探讨架构,交流源码。加入方式,长按下方二维码噢

b78b9737941cb01a22589d10b64789df.png

已在知识星球更新源码解析如下:

082b7a3c833e053b1b5edbd00df48883.png

56d16c40cd043158c2c847339f2f1c42.png

0ceebaa77f038a881939bc7db4cdeae2.png

42bb78679e32f160b3611c5909c7524f.png

最近更新《芋道 SpringBoot 2.X 入门》系列,已经 101 余篇,覆盖了 MyBatis、Redis、MongoDB、ES、分库分表、读写分离、SpringMVC、Webflux、权限、WebSocket、Dubbo、RabbitMQ、RocketMQ、Kafka、性能测试等等内容。

提供近 3W 行代码的 SpringBoot 示例,以及超 6W 行代码的电商微服务项目。

获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。

  1. 文章有帮助的话,在看,转发吧。
  2. 谢谢支持哟 (*^__^*)

发表评论

表情:
评论列表 (有 0 条评论,312人围观)

还没有评论,来说两句吧...

相关阅读