ThreadLocal在Spring事务管理中的应用
ThreadLocal是用来处理多线程并发问题的一种解决方案。ThreadLocal是的作用是提供线程的局部变量,在多线程并发环境下,提供了与其他线程隔离的局部变量。通常这样的设计的情况是因为这个局部变量是不适合放在全局变量进行同步处理的。比如在事务管理中,在service类中的涉及到事务的方法,每个事务的上下文都应该是独立拥有数据库的connection连接的,否则在数据提交回滚过程中就会产生冲突。
spring中使用ThreadLocal来设计TransactionSynchronizationManager类,实现了事务管理与数据访问服务的解耦,同时也保证了多线程环境下connection的线程安全问题。
DataSourceTransactionManager的实现中,doBegin()方法开启事务,我们看下它是怎么处理connection资源的。

首先从数据库连接池中获得一个connection,并构造一个connection包装类,使用这个包装类开启事务,最后通过TransactionSynchronizationManager将connection与ThreadLocal绑定,事务提交或者回滚后,解除绑定。
TransactionSynchronizationManager中bindResource()的实现

Resource就是ThreadLocal,而这里的Map就是ThreadLocalMap的value,与当前线程关联的ThreadLocal的值。
ThreadLocal又是如何为每个线程维护一个独立的局部变量的呢?
首先在Thread类中,都会维护一个ThreadLocalMap映射表,这个映射表存储的key是ThreadLocal本身,value则是我们存储的局部变量object。
ThreadLocal类中get方法和set方法的实现。
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null)
return (T)e.value;
}
return setInitialValue();
}
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
我们再看getMap的实现
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
从代码实现中可以看出,每个线程Thread都会维护自己的ThreadLocalMap,这个map的key则是ThreadLocal类本身,而value则是我们保存的数据。ThreadLocal在多线程中是被公共持有的,被隔离的数据实际是存放在每个线程的ThreadLocalMap中的,只不过是通过ThreadLocal的引用得到每个线程维护的ThreadLocalMap中的value。
ThreadLocal在Spring事务管理中的应用的更多相关文章
- Spring事务管理中的配置文件(三)
在开发中,遇到了sql语句报错,但是并没有回滚的情况. 经过几天的排查,终于找到了事务没有回滚的原因. 原来的项目用的是informix的数据库,原来针对事务回滚的机制都是好用的.我本地用的是mysq ...
- Spring事务管理——其他的事务属性
之前我们说过Spring事务管理中的事务的传播行为的属性.下面我们来说一下它的其他属性. 一.事务的隔离级别 1 .数据库事务并发问题.假设现在有两个事务:Transaction01和Transact ...
- Spring事务管理——回滚(rollback-for)控制
探讨Spring事务控制中,异常触发事务回滚原理.文章进行了6种情况下的Spring事务是否回滚. 以下代码都是基于Spring与Mybatis整合,使用Spring声明式事务配置事务方法. 1.不捕 ...
- spring事务管理及相关知识
最近在项目中遇到了spring事务的注解及相关知识,突然间感觉自己对于这部分知识只停留在表面的理解层次上,于是乎花些时间上网搜索了一些文章,以及对于源码的解读,整理如下: 一.既然谈到事务,那就先搞清 ...
- 【Java EE 学习 52】【Spring学习第四天】【Spring与JDBC】【JdbcTemplate创建的三种方式】【Spring事务管理】【事务中使用dbutils则回滚失败!!!??】
一.JDBC编程特点 静态代码+动态变量=JDBC编程. 静态代码:比如所有的数据库连接池 都实现了DataSource接口,都实现了Connection接口. 动态变量:用户名.密码.连接的数据库. ...
- spring事务管理器设计思想(一)
在最近做的一个项目里面,涉及到多数据源的操作,比较特殊的是,这多个数据库的表结构完全相同,由于我们使用的ibatis框架作为持久化层,为了防止每一个数据源都配置一套规则,所以重新实现了数据源,根据线程 ...
- Spring 事务管理原理探究
此处先粘贴出Spring事务需要的配置内容: 1.Spring事务管理器的配置文件: 2.一个普通的JPA框架(此处是mybatis)的配置文件: <bean id="sqlSessi ...
- Spring 事务管理高级应用难点剖析--转
第 1 部分 http://www.ibm.com/search/csass/search/?q=%E4%BA%8B%E5%8A%A1&sn=dw&lang=zh&cc=CN& ...
- Spring 事务管理高级应用难点剖析: 第 1 部分
Spring 的事务管理是被使用得最多的功能之一,虽然 Spring 事务管理已经帮助程序员将要做的事情减到了最小.但在实际开发中,如果使用不当,依然会造成数据连接泄漏等问题.本系列以实际应用中所碰到 ...
随机推荐
- Kotlin学习(5)类型系统
可空性(避免空指针异常) /* *这个函数的参数代表传入一个String类型变量的实例,这代表它不可以为空 */ fun a(str:String){ println(str) } //这样调用a() ...
- 重写select
select 模拟 目前仿写select的方式 给tableIndex 来使 div(无法获取焦点的元素)来获取元素,这样便可以在失去焦点时,是否将下拉框收回 通过 document的点击,来判断是否 ...
- jQuery之样式的类操作
方法:添加类addClass .删除类removeClass. 切换类toggleClass <style> div { width: 150px; height: 150px; b ...
- html5移动端Meta的设置
强制让文档的宽度与设备的宽度保持1:1,并且文档最大的宽度比例是1.0,且不允许用户点击屏幕放大浏览 1 <meta name="viewport" content=&quo ...
- Math、Date内置对象方法整理
Math : 内置的对象(构造函数)静态属性或静态方法. 一. Math.PI : 圆周率 ...
- 从零开始配置安装Flutter开发环境
flutter 中文网 https://flutterchina.club/get-started/install/ 1.配置全局环境 PUB_HOSTED_URL=https://pub.flutt ...
- JSP页面包含其他页面的三种方式及区别
一. <%@ include file="header.inc"%> 该指令在编译之前先读入指定的页面中的内容(并不对动态内容求值),融合后的完整页面再被整体的转换为一 ...
- Linux 设置定时清除buff/cache的脚本
Linux 设置定时清除buff/cache的脚本 查看内存缓存状态 [root@heyong ~]# free -m total used free shared buff/cache availa ...
- 来到园子的第two天!!!!!
经过这几天的打字练习 从练习的第一天到今天(应该是第三天吧) 从67到133字/分钟,我练的是英文文章测试,总的来说挺不容易 ,感觉后几天提升就不好提了呀 不说废话了 简单说一下今天的收获吧 都是 ...
- GUI学习之三十三——QProgressBar学习总结
今天总结的是QProgressBar的使用方法 一.描述 提供了一个水平或垂直的进度条,用于向用户提供操作进度的指示,用户也可以从进度条看出来程序是否正在运行. 二.功能作用 1.设置范围和当前值 Q ...