将connection存放在Threadlocal里和数据库连接池的区别

wokaole 2008-07-31 10:26:14
我有几点不太明白的,望各位大侠指教下。
1、j2ee的应用中,有一个用户请求就会启动一个线程。而如果我们把connection放在Threadlocal里的话,那么我们的程序只需要一个connection连接数据库就行了,每个线程都是用的connection的一个副本,那为什么还有必要要数据库连接池呢?
2、在这种情况下一个副本里的connection执行了关闭操作,其他都没执行。那么想问一下真正与数据库连接的connection什么时候关闭呢?
3、显然上面的第一个问题是不成立的,但是希望哪位大侠帮我解释下。解释下什么时候是从数据库连接池里取connection而什么时候获得的是connection的一个Threadlocal副本?
...全文
1439 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
drogenflynet 2012-01-18
  • 打赏
  • 举报
回复
学习了
obullxl 2011-09-03
  • 打赏
  • 举报
回复
用连接池是为了缓存已经打开的连接,提高性能;用ThreadLocal是为了多个数据库操作是用的同一个连接,是为了事务;两个是不同的目的的。
liumm0609 2010-04-12
  • 打赏
  • 举报
回复
在一个线程是里面,因为是同一个连接(connection),所以方便进行事务管理,当然如果所谓的原子操作仅仅涉及一个个操作,那就无所谓了。
cshenheart 2008-10-06
  • 打赏
  • 举报
回复
谢谢12楼的,你说的是我要的答案。
private ThreadLocal <Connection> ct = new ThreadLocal <Connnection>();
这行代码保证每一个线程都有一个自己独立的Connection,这是这行代码的作用。
至于Connection是去新建立,还是从连接池取出来,这是连接池要去解决的。

如果不用private ThreadLocal <Connection> ct = new ThreadLocal <Connnection>();
有可能发生多个线程使用同一个Connection的问题。

自己的理解。
lllove 2008-08-02
  • 打赏
  • 举报
回复
如11楼所说,一个事务涉及多个 DAO 操作.
yuanyemars 2008-08-02
  • 打赏
  • 举报
回复
...首先,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就是连接池的问题了,你也管不到.
wokaole 2008-08-02
  • 打赏
  • 举报
回复
谢谢各位的热心回复。可能是我的标题起得不好引起了大家说我概念混淆的问题,道歉。11楼的正是我想要的答案,非常的感谢。
  • 打赏
  • 举报
回复
由于请求中的一个事务涉及多个 DAO 操作,而这些 DAO 中的 Connection
不能从连接池中获得,如果是从连接池获得的话,两个 DAO 就用到了两个
Connection,这样的话是没有办法完成一个事务的。

DAO 中的 Connection 如果是从 ThreadLocal 中获得 Connection 的话那
么这些 DAO 就会被纳入到同一个 Connection 之下。当然了,这样的话,
DAO 中就不能把 Connection 给关了,关掉的话,下一个使用者就不能用了。
wokaole 2008-08-01
  • 打赏
  • 举报
回复
to 8楼的:
首先感谢下。我知道是保证一个线程下一个事务的。我就是不太明白:正如我在7楼描述的那种情况下,

如果不用threadlocal,能出现一个线程不是一个事务的情况吗。数据库连接池的原理我也知道,threadlocal的实现我也知道。我就是不明白不用threadlocal在什么情况下会出现事务不一致的异常,以及为什么会这样。
wokaole 2008-08-01
  • 打赏
  • 举报
回复
怎么就是没人回呢?哪位能帮忙讲讲啊。
J2EE_yws 2008-08-01
  • 打赏
  • 举报
回复
我手上有他的原代码,下次有机会发给你看
现在在网吧上网
J2EE_yws 2008-08-01
  • 打赏
  • 举报
回复
ThreadLocal是保证一个线程一个事务一个session
wokaole 2008-08-01
  • 打赏
  • 举报
回复 1
to 5楼的:
谢谢您的回答。这两个概念不是一回事儿我是知道的。我这样问吧。
你是说threadlocal解决事务问题。同一个线程调用的是同一个connection,因此和其他线程不会冲突。是可以这样理解的吧。
那么我想问,假设我们不放在threadlocal里面会是什么情况呢?
假设有一个请求来了,它开启了一个线程,从数据库连接池中获得了一个链接,并且这个线程它执行一套数据库事务的相关操作,它正在进行的过程中。这时又来了一个请求,它也有一套数据库事务的操作,并且也从数据库连接池中获得一个connection。那么第一个请求的connection和这第二个请求的connection都是从连接池获得的,他们之间也不冲突,那这时候还要threadlocal有什么用呢。
我的问题是为什么在有数据库连接池的情况下还要加入threadlocal这个线程变量。
lllove 2008-08-01
  • 打赏
  • 举报
回复
楼主在吗?也帮我回答下问题吧 http://topic.csdn.net/u/20080801/18/72c023e5-7320-4664-ae8c-6b787c812e63.html
lllove 2008-08-01
  • 打赏
  • 举报
回复
1.threadlocal和数据库连接池不是一概念,连接池是缓存连接,主要是为了提高性能。一般从连接池中拿到连接,放到threadlocal中,这样能解决的事务问题,不管调用哪个方法,同一个线程使用的是同一个连接。

2.没有什么副本吧,你拿到的连接就在threadlocal中,用完关掉就行了,它会返回连接池中。

3.很奇怪的问题,建议楼主先搞清楚概念
Baby_2007 2008-08-01
  • 打赏
  • 举报
回复
不知道,帮顶一下
wokaole 2008-07-31
  • 打赏
  • 举报
回复
怎么没人回呢?难道这个问题太傻了。可是我真的在这个问题上犯糊涂了,忘各位帮帮忙啊。

67,512

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧