1.threadlocal和数据库连接池不是一概念,连接池是缓存连接,主要是为了提高性能。一般从连接池中拿到连接,放到threadlocal中,这样能解决的事务问题,不管调用哪个方法,同一个线程使用的是同一个连接。2.没有什么副本吧,你拿到的连接就在threadlocal中,用完关掉就行了,它会返回连接池中。3.很奇怪的问题,建议楼主先搞清楚概念

解决方案 »

  1.   

    楼主在吗?也帮我回答下问题吧 http://topic.csdn.net/u/20080801/18/72c023e5-7320-4664-ae8c-6b787c812e63.html
      

  2.   

    to 5楼的:
    谢谢您的回答。这两个概念不是一回事儿我是知道的。我这样问吧。
    你是说threadlocal解决事务问题。同一个线程调用的是同一个connection,因此和其他线程不会冲突。是可以这样理解的吧。
    那么我想问,假设我们不放在threadlocal里面会是什么情况呢?
    假设有一个请求来了,它开启了一个线程,从数据库连接池中获得了一个链接,并且这个线程它执行一套数据库事务的相关操作,它正在进行的过程中。这时又来了一个请求,它也有一套数据库事务的操作,并且也从数据库连接池中获得一个connection。那么第一个请求的connection和这第二个请求的connection都是从连接池获得的,他们之间也不冲突,那这时候还要threadlocal有什么用呢。
    我的问题是为什么在有数据库连接池的情况下还要加入threadlocal这个线程变量。
      

  3.   

    ThreadLocal是保证一个线程一个事务一个session
      

  4.   

    to 8楼的:
    首先感谢下。我知道是保证一个线程下一个事务的。我就是不太明白:正如我在7楼描述的那种情况下,如果不用threadlocal,能出现一个线程不是一个事务的情况吗。数据库连接池的原理我也知道,threadlocal的实现我也知道。我就是不明白不用threadlocal在什么情况下会出现事务不一致的异常,以及为什么会这样。
      

  5.   

    由于请求中的一个事务涉及多个 DAO 操作,而这些 DAO 中的 Connection 
    不能从连接池中获得,如果是从连接池获得的话,两个 DAO 就用到了两个
    Connection,这样的话是没有办法完成一个事务的。DAO 中的 Connection 如果是从 ThreadLocal 中获得 Connection 的话那
    么这些 DAO 就会被纳入到同一个 Connection 之下。当然了,这样的话,
    DAO 中就不能把 Connection 给关了,关掉的话,下一个使用者就不能用了。
      

  6.   

     ...首先,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就是连接池的问题了,你也管不到.
      

  7.   

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

  8.   

    谢谢12楼的,你说的是我要的答案。
    private ThreadLocal <Connection> ct = new ThreadLocal <Connnection>(); 
    这行代码保证每一个线程都有一个自己独立的Connection,这是这行代码的作用。
    至于Connection是去新建立,还是从连接池取出来,这是连接池要去解决的。如果不用private ThreadLocal <Connection> ct = new ThreadLocal <Connnection>();
    有可能发生多个线程使用同一个Connection的问题。自己的理解。
      

  9.   

    在一个线程是里面,因为是同一个连接(connection),所以方便进行事务管理,当然如果所谓的原子操作仅仅涉及一个个操作,那就无所谓了。
      

  10.   

    用连接池是为了缓存已经打开的连接,提高性能;用ThreadLocal是为了多个数据库操作是用的同一个连接,是为了事务;两个是不同的目的的。