博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
透彻理解Spring事务设计思想之手写实现
阅读量:6489 次
发布时间:2019-06-24

本文共 1300 字,大约阅读时间需要 4 分钟。

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

65c753ce2e95060870424c5bf29a090773617bd1

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

先来看一眼工程结构:

c56963751443d086889d7a5757d382d24d7fa3bc

工程结构

ConnectionHolder

e4a0857ad913bb7e5b1ce883edcc1771132ae909

ConnectionHolder

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

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

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

SingleThreadConnectionHolder

8e855f180fb603372e1131949f92f0673a8a282c

SingleThreadConnectionHolder

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

TransactionManager

caf8376fe19357c3b2667061c7324fe371a9d7c5

TransactionManager

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

UserAccountDao、UserOrderDao

446d30588bcd8d55e5bcc486f6cd067b72f2ddf9

UserAccountDao

b2737f5343ab73fa69022ba396b109be4739dc61

UserOrderDao

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

UserService

aa96036744e06a482727fd2284e18adaf6c10863

UserService

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

Test

f7075d5b5a33d487db218d2a0c68df6c1ae05765

测试

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

运行结果

24c8c044678fb8b133f55dd15555cfe5a7d549be

运行结果

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

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

原文发布时间为:2018-09-12

本文作者:张丰哲

本文来自云栖社区合作伙伴“ java进阶架构师”,了解相关信息可以关注“ java进阶架构师”。

转载地址:http://gyouo.baihongyu.com/

你可能感兴趣的文章
loadrunner下的putty和plink
查看>>
鼠标右键添加"在此处打开命令窗口"
查看>>
exadata(硬件更换文档部分)
查看>>
Asp.Net Core WebAPI入门整理(一)
查看>>
CSS Text
查看>>
Android 防内存泄露handler
查看>>
Redis整合Spring结合使用缓存实例
查看>>
【POJ 3292】 Semi-prime H-numbers
查看>>
时空的乐章
查看>>
Linux中Sed的用法
查看>>
腾讯 AlloyCrop 1.0 发布
查看>>
第三百四十节,Python分布式爬虫打造搜索引擎Scrapy精讲—css选择器
查看>>
js 字符串转换成数字的三种方法
查看>>
《JAVA与模式》之代理模式
查看>>
【dotnet跨平台】Asp.net 正在经历的变革
查看>>
Sql控制反转小尝试
查看>>
checkmysql.sh
查看>>
Android按键添加和处理的方案【转】
查看>>
如何让 Xcode 在读写上提速100倍?
查看>>
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password)
查看>>