Java 数据库连接与线程安全

Screen Shot 2020-01-17 at 2.54.35 PM.png

Screen Shot 2020-01-17 at 2.55.09 PM.png

Question1

作者说 为了确保一个线程中只有一个Connection, 我们可以使用 ThreadLocal来存放本地线程变量. 这句话本身没有问题, 但是示例代码中是通过 DriverManager.getConnection 来创建的连接, 也就是说每个连接都是全新的, 不是从连接池里取的, 也就没有线程安全问题, 没有必要使用 ThreadLocal 隔离变量.
请问我这样理解是对的吗?

Question2

当从数据库连接池中取连接的时候, 线程安全的问题是怎么产生的呢? 难道一个 Connection 资源在没有释放的情况下会再次分配出去吗?

阅读 4k
3 个回答

上下文有点少,不是很清楚这里用ThreadLocal共享连接的目的

一个线程所执行的代码逻辑中可能会多次获取连接,而且需要获取到同一个连接。因为业务逻辑要执行的SQL语句通常要处在同一个事务中,同一个事务需要同一个连接,所以用ThreadLocal是一件很自然的事情

数据库连接池只是管理连接,自身应该是线程安全的,但是Connection是否线程安全(通常不)和数据库连接池也没有什么关系

可以参照下spring的 jdbctemplate

题目中的这一段代码是没有使用数据库连接池的。

每当需要获取一个数据库连接时,都先去看看TheadLocal是否存在连接,没有连接的话,就创建一个连接,放入TheadLocal中。当前线程后续还要使用数据库连接的时候,就从TheadLocal中取出先前创建的连接,这样就不用再去创建连接了。在没有使用数据库连接池的情况是,这种使用ThreadLocal的办法不仅减少了创建连接时资源的消耗,同时创建的连接只对当前线程可见,保证了数据库连接的线程安全。所以用TheadLocal还是有必要的。

对于第二个问题,如果从数据库连接池中获取的一个连接,在多个线程中使用,就会出现线程不安全的情况。平时我们使用的框架,比如Mybatis已经隐藏了这些细节,所以不会出现线程不安全的情况

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题