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 事务管理已经帮助程序员将要做的事情减到了最小.但在实际开发中,如果使用不当,依然会造成数据连接泄漏等问题.本系列以实际应用中所碰到 ...
随机推荐
- debian上安装mysql server
1 将mysql添加到apt的repository中 第一步,下载mysql提供的ppa文件 wget https://dev.mysql.com/get/mysql-apt-config_0.8.1 ...
- Linux环境安装mongodb
介绍 上篇介绍了Linux环境下安装Node.js的步骤,紧接着来安装mongodb.另外,推荐我的另一篇 Windows下图文详解Mongodb安装及配置,先在Windows下熟悉下mongodb, ...
- [2019上海网络赛F题]Rhyme scheme
题目链接 题意,求出合法的长度为n的字典序第k小字符串,合法的定义为除了最后一位,每一位的取值范围为'A'到'A'+pos-1,而最后一位的取值范围'A'到当前字符串最大值+1. 队友tql,Orz ...
- SI 和 MDK 添加Astyle功能
一. 什么是Astyle 1. Astyle是一个用来对C/C++代码进行格式化的插件,可在多个环境中使用.该插件基于 Artistic Style 开发 二. 软件获取地址 1.下载地址:https ...
- __init__ 和__new__的区别?
init 在对象创建后,对对象进行初始化. new 是在对象创建之前创建一个对象,并将该对象返回给 init.
- mysql之sql性能调优
sql调优大致分为两步:1 如何定位慢查询 2 如何优化sql语句. 一:定位慢查询 -- 显示到mysql数据库的连接数 -- show status like 'connections'; - ...
- ajax使用jsonp跨域调用webservice error错误信息"readyState":4,"status":200,"statusText":"success"
主要还是接口写有问题 至于ajax保持简洁写法即可 $.ajax({ dataType: 'jsonp', type: ‘get’, data: {}, url: '' })
- mysql的innodb 引擎 表锁与行锁
innodb 引擎 行锁与表锁 行锁与表锁是基于索引来说的(且索引要生效) 不带索引 (表锁)要全表扫描 1. 执行select @@autocommit; 查看结果 0是不自动提交事务,1是自动提交 ...
- Linux日常之定时向文件传内容
一. Linux中定时执行任务使用的命令是crontab 流程如下: 1. 使用命令crontab -e进入编辑界面 2. [Ctrl]+X进行保存退出 3. 重启crontab服务,这样才可以生效, ...
- Saving James Bond - Easy Version
题目来源: 浙江大学在慕课网上开设的<数据结构>课,陈越老师.何钦铭老师主讲,课后作业的一道题. 题目描述: 题目思路: 这道题目本质上讲就是列出图的连通集,但是这个连通集的起点是有约束的 ...