图片来自网络
** 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 实现事务的思想有所了解呢?
Android 开发资料 + 面试架构资料 免费分享 点击链接 即可领取
《Android 架构师必备学习资源免费领取 (架构视频 + 面试专题文档 + 学习笔记)》
来源: http://www.jianshu.com/p/0b54723feab9