to 5楼的: 谢谢您的回答。这两个概念不是一回事儿我是知道的。我这样问吧。 你是说threadlocal解决事务问题。同一个线程调用的是同一个connection,因此和其他线程不会冲突。是可以这样理解的吧。 那么我想问,假设我们不放在threadlocal里面会是什么情况呢? 假设有一个请求来了,它开启了一个线程,从数据库连接池中获得了一个链接,并且这个线程它执行一套数据库事务的相关操作,它正在进行的过程中。这时又来了一个请求,它也有一套数据库事务的操作,并且也从数据库连接池中获得一个connection。那么第一个请求的connection和这第二个请求的connection都是从连接池获得的,他们之间也不冲突,那这时候还要threadlocal有什么用呢。 我的问题是为什么在有数据库连接池的情况下还要加入threadlocal这个线程变量。
ThreadLocal是保证一个线程一个事务一个session
to 8楼的: 首先感谢下。我知道是保证一个线程下一个事务的。我就是不太明白:正如我在7楼描述的那种情况下,如果不用threadlocal,能出现一个线程不是一个事务的情况吗。数据库连接池的原理我也知道,threadlocal的实现我也知道。我就是不明白不用threadlocal在什么情况下会出现事务不一致的异常,以及为什么会这样。
由于请求中的一个事务涉及多个 DAO 操作,而这些 DAO 中的 Connection 不能从连接池中获得,如果是从连接池获得的话,两个 DAO 就用到了两个 Connection,这样的话是没有办法完成一个事务的。DAO 中的 Connection 如果是从 ThreadLocal 中获得 Connection 的话那 么这些 DAO 就会被纳入到同一个 Connection 之下。当然了,这样的话, DAO 中就不能把 Connection 给关了,关掉的话,下一个使用者就不能用了。
谢谢您的回答。这两个概念不是一回事儿我是知道的。我这样问吧。
你是说threadlocal解决事务问题。同一个线程调用的是同一个connection,因此和其他线程不会冲突。是可以这样理解的吧。
那么我想问,假设我们不放在threadlocal里面会是什么情况呢?
假设有一个请求来了,它开启了一个线程,从数据库连接池中获得了一个链接,并且这个线程它执行一套数据库事务的相关操作,它正在进行的过程中。这时又来了一个请求,它也有一套数据库事务的操作,并且也从数据库连接池中获得一个connection。那么第一个请求的connection和这第二个请求的connection都是从连接池获得的,他们之间也不冲突,那这时候还要threadlocal有什么用呢。
我的问题是为什么在有数据库连接池的情况下还要加入threadlocal这个线程变量。
首先感谢下。我知道是保证一个线程下一个事务的。我就是不太明白:正如我在7楼描述的那种情况下,如果不用threadlocal,能出现一个线程不是一个事务的情况吗。数据库连接池的原理我也知道,threadlocal的实现我也知道。我就是不明白不用threadlocal在什么情况下会出现事务不一致的异常,以及为什么会这样。
不能从连接池中获得,如果是从连接池获得的话,两个 DAO 就用到了两个
Connection,这样的话是没有办法完成一个事务的。DAO 中的 Connection 如果是从 ThreadLocal 中获得 Connection 的话那
么这些 DAO 就会被纳入到同一个 Connection 之下。当然了,这样的话,
DAO 中就不能把 Connection 给关了,关掉的话,下一个使用者就不能用了。
线程池,为避免不必要的创建,销毁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就是连接池的问题了,你也管不到.
private ThreadLocal <Connection> ct = new ThreadLocal <Connnection>();
这行代码保证每一个线程都有一个自己独立的Connection,这是这行代码的作用。
至于Connection是去新建立,还是从连接池取出来,这是连接池要去解决的。如果不用private ThreadLocal <Connection> ct = new ThreadLocal <Connnection>();
有可能发生多个线程使用同一个Connection的问题。自己的理解。