数据库连接池中是将connection放进threadlocal里的

Posted THISISPAN

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据库连接池中是将connection放进threadlocal里的相关的知识,希望对你有一定的参考价值。

我有几点不太明白的,望各位大侠指教下。
1、j2ee的应用中,有一个用户请求就会启动一个线程。而如果我们把connection放在Threadlocal里的话,那么我们的程序只需要一个connection连接数据库就行了,每个线程都是用的connection的一个副本,那为什么还有必要要数据库连接池呢?
2、在这种情况下一个副本里的connection执行了关闭操作,其他都没执行。那么想问一下真正与数据库连接的connection什么时候关闭呢?

3、显然上面的第一个问题是不成立的,但是希望哪位大侠帮我解释下。解释下什么时候是从数据库连接池里取connection而什么时候获得的是connection的一个Threadlocal副本?

 

 

答复1:

 

由于请求中的一个事务涉及多个 DAO 操作,而这些 DAO 中的 Connection 
不能从连接池中获得,如果是从连接池获得的话,两个 DAO 就用到了两个
Connection,这样的话是没有办法完成一个事务的。

DAO 中的 Connection 如果是从 ThreadLocal 中获得 Connection 的话那
么这些 DAO 就会被纳入到同一个 Connection 之下。当然了,这样的话,
DAO 中就不能把 Connection 给关了,关掉的话,下一个使用者就不能用了。

 

如11楼所说,一个事务涉及多个 DAO 操作.

 

答复2:

...首先,LZ是概念上的错误.什么是线程池,什么是ThreadLocal???
   线程池,为避免不必要的创建,销毁connection而存在的,其中包括活动,等待,最小等属性,cop3,proxy连接池都可以配置这些玩意;
   
   至于为什么要用ThreadLocal呢?这个和连接池无关,我认为更多的是和程序本身相关,为了更清楚的说明,我举个例子
   servlet中获取一个连接.首先,servlet是线程安全的吗?
     class MyServlet extends HttpServlet{
         private Connection conn;
     }
     ok,遗憾的告诉你,这个conn并不是安全的,所有请求这个servlet的连接,使用的都是一个Connection,这个就是致命的了.多个人使用同一个连接,算上延迟啥的,天知道数据会成什么样.
     因此我们要保证Connection对每个请求都是唯一的.这个时候就可以用到ThreadLocal了,保证每个线程都有自己的连接.
     改为 private ThreadLocal<Connection> ct = new ThreadLocal<Connnection>();
     然后从连接池获取Connection,set到ct中,再get就行了,至于得到的是哪个Connection就是连接池的问题了,你也管不到.

以上是关于数据库连接池中是将connection放进threadlocal里的的主要内容,如果未能解决你的问题,请参考以下文章

从 Tomcat DBCP JDBC 连接池中获取 Connection 对象

Tomcat数据源--DataSource&Connection Pool

C3P0NativeJdbcExtractor 上的 Connection.close() 关闭连接并将其从池中删除

Java Connection Pool 和 try-with 语句:连接实际上是关闭还是返回到池中?

数据源,连接池,连接,jndi

DBCP连接及MySQL优化