数据库连接池为什么要用threadlocal呢?不用会怎样?

沙海 2021年5月27日04:14:00Java评论27字数 2265阅读7分33秒阅读模式
摘要

速读摘要

速读摘要文章源自JAVA秀-https://www.javaxiu.com/26496.html

ThreadLocal缓存连接,是为了把同一个数据库连接"分享"给同一个线程的不同调用方法。Connection是从ThreadLocal中获得的(意味着都是同一个对象),那么这些DAO就会被纳入到同一个Connection之下。同一个线程在多个地方)从连接池中拿到的Connection,肯定不是同一个连接。为了确保不同时间多个线程可能拿到的是同一个连接,那么此时threadlocal闪亮登场,就算我拿的是"同一个连接",在引入了threadlocal后,每个线程之间都会创建独立的连接副本,将collection各自copy一份,这样就互相不干扰了。文章源自JAVA秀-https://www.javaxiu.com/26496.html

原文约 1669 | 图片 3 | 建议阅读 4 分钟 | 评价反馈文章源自JAVA秀-https://www.javaxiu.com/26496.html

数据库连接池为什么要用threadlocal呢?不用会怎样?

戳一戳→ 程序员的成长之路 文章源自JAVA秀-https://www.javaxiu.com/26496.html

数据库连接池为什么要用threadlocal呢?不用会怎样?文章源自JAVA秀-https://www.javaxiu.com/26496.html

程序员的成长之路文章源自JAVA秀-https://www.javaxiu.com/26496.html

互联网/程序员/技术/资料共享 文章源自JAVA秀-https://www.javaxiu.com/26496.html

关注文章源自JAVA秀-https://www.javaxiu.com/26496.html

阅读本文大概需要 3 分钟。文章源自JAVA秀-https://www.javaxiu.com/26496.html

来自:blog.csdn.net/qq_42405666/article/details/108258820文章源自JAVA秀-https://www.javaxiu.com/26496.html

这个问题我疑问了很久很久,主要如下截图。文章源自JAVA秀-https://www.javaxiu.com/26496.html

数据库连接池为什么要用threadlocal呢?不用会怎样?文章源自JAVA秀-https://www.javaxiu.com/26496.html

个连接对应一个事务,多个连接的事务是不一样的,先大概了解一下,往下看?文章源自JAVA秀-https://www.javaxiu.com/26496.html

本人是在学threadlocal的时候,网上大部分人都是说数据库连接池是典型的用了threadloca的例子,然后我就又查数据库连接池和threadloca的关系,但是,99%都说threadlocal是为了在并发的情况下,为了保证线程安全,创建了副本什么的,其实这只是threadlocal的用法之一,它还有个用法就是确保同一线程之间参数传递的方便(扯远了)文章源自JAVA秀-https://www.javaxiu.com/26496.html

回归正题,还是拿上面的图来说事。。。。文章源自JAVA秀-https://www.javaxiu.com/26496.html

我只讲两个关键点,明白人一看就懂:文章源自JAVA秀-https://www.javaxiu.com/26496.html

1、两者有根本性的区别,用处不一样!

连接池是缓存并托管数据库连接,主要是为了提高性能。文章源自JAVA秀-https://www.javaxiu.com/26496.html

而ThreadLocal缓存连接,是为了把同一个数据库连接“分享”给同一个线程的不同调用方法。(不管调用哪个方法,都是使用的同一个连接,方便进行“跨方法”的事务控制)文章源自JAVA秀-https://www.javaxiu.com/26496.html

举个栗子:文章源自JAVA秀-https://www.javaxiu.com/26496.html

如果一个请求中涉及多个 DAO 操作,而如果这些DAO中的Connection都是独立的话,就没有办法完成一个事务。但是如果DAO 中的 Connection 是从 ThreadLocal 中获得的(意味着都是同一个对象), 那么这些 DAO 就会被纳入到同一个 Connection 之下。文章源自JAVA秀-https://www.javaxiu.com/26496.html

2、重点要理解“连接池”。

连接池里面有一定数量的连接资源,比如最大20个连接。文章源自JAVA秀-https://www.javaxiu.com/26496.html

题外话:如果直接通过 Java原生API 获取“直连”的话:文章源自JAVA秀-https://www.javaxiu.com/26496.html

底层方法一般都是这样写的:文章源自JAVA秀-https://www.javaxiu.com/26496.html

java.sql.DriverManager.getConnection(url, props);java.sql.Driver.connect(url, props);

特点是:要传入url、用户名和密码等信息)文章源自JAVA秀-https://www.javaxiu.com/26496.html

这种方式,肯定就没有使用数据库连接池。文章源自JAVA秀-https://www.javaxiu.com/26496.html

使用数据库连接池,通常都是得到一个所谓的javax.sql.DataSource[接口]的实例对象,它里面包含了Connection,并且数据库连接池工具类(比如C3P0、JNDI、DBCP等),肯定是重新定义了getConnection、closeConnection等方法,所以你每次得到的Connection,几乎都不是新建立的连接(而是已经建立好并放到缓存里面的连接),你调用closeConnection方法,也不是真正的关闭连接(一般都是起到一个标识作用,标识当前连接已经使用完毕,归还给连接池,让这个连接处于待分配状态)文章源自JAVA秀-https://www.javaxiu.com/26496.html

PS:所以说:使用数据库连接池时,还是要显式的调用数据库连接池API提供的关闭连接的方法。文章源自JAVA秀-https://www.javaxiu.com/26496.html

理解一下这句话:文章源自JAVA秀-https://www.javaxiu.com/26496.html

不同的线程在同一个时间( 或者 同一个线程在多个地方)从连接池中拿到的Connection,肯定不是同一个连接。(反过来讲:不同时间的两个线程,一前一后,则有可能拿到同一个连接)文章源自JAVA秀-https://www.javaxiu.com/26496.html

总结:

再好好理解一下上面的一段话,我再最后解释亿下。。。文章源自JAVA秀-https://www.javaxiu.com/26496.html

  • 首先,我们为了避免单一数据库连接的创建和关闭耗费时间和性能,引入了数据库连接池,提前创建好了n条连接放入池中,如果是单线程情况下,那这样挺好的文章源自JAVA秀-https://www.javaxiu.com/26496.html

  • 那如果是多线程情况下呢?还是上面那段话,假设同一时间多个线程从数据库连接池获取连接,那肯定拿的是不同的连接,我当前线程和别的线程拿的连接不一样,那我当前在crud的时候,不在一个事务之内。文章源自JAVA秀-https://www.javaxiu.com/26496.html

  • 假设不同时间的多个线程要从数据库连接池拿连接,那这个时候就可能拿到的是同一个连接了,那我多个线程线程拿到的是同一个连接,也就是说在多个线程在同一个事务之内,线程a执行了插入还没来得及提交,线程b此时来了个更新,在线程a还未操作完之前,线程b更新完了后,直接把连接给close了,线程a插了一半发现插不了了。。。此时肯定在想,这™是谁在搞我。文章源自JAVA秀-https://www.javaxiu.com/26496.html

  • 为了确保不同时间多个线程可能拿到的是同一个连接,那么此时threadlocal闪亮登场,就算我拿的是“同一个连接”,在引入了threadlocal后,每个线程之间都会创建独立的连接副本,将collection各自copy一份,这样就互相不干扰了。文章源自JAVA秀-https://www.javaxiu.com/26496.html

以上是我的个人见解。文章源自JAVA秀-https://www.javaxiu.com/26496.html

<END>文章源自JAVA秀-https://www.javaxiu.com/26496.html

推荐阅读:文章源自JAVA秀-https://www.javaxiu.com/26496.html

你们期待已久的微信功能,它终于要来了文章源自JAVA秀-https://www.javaxiu.com/26496.html

快来试试 Spring Boot 应用可视化监控,一目了然!文章源自JAVA秀-https://www.javaxiu.com/26496.html

最近面试BAT,整理一份面试资料《Java面试BATJ通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。

文章源自JAVA秀-https://www.javaxiu.com/26496.html

获取方式:点个「在看」,点击上方小卡片,进入公众号后回复「面试题」领取,更多内容陆续奉上。文章源自JAVA秀-https://www.javaxiu.com/26496.html

朕已阅 数据库连接池为什么要用threadlocal呢?不用会怎样?文章源自JAVA秀-https://www.javaxiu.com/26496.html

继续阅读
速蛙云 - 极致体验,强烈推荐!!!购买套餐就免费送各大视频网站会员!快速稳定、独家福利社、流媒体稳定解锁!速度快,全球上网、视频、游戏加速、独立IP均支持!基础套餐性价比很高!这里不多说,我一直正在使用,推荐购买:https://www.javaxiu.com/59919.html
weinxin
资源分享QQ群
本站是JAVA秀团队的技术分享社区, 会经常分享资源和教程; 分享的时代, 请别再沉默!
沙海
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定