多个线程可以共享同一个数据库连接同时执行多个prepareStatement吗?

时间:2021-04-06 09:27:01

标签: jdbc

我想使用多个线程来执行 SQL 查询。每个线程分配一个数据库连接会造成很大的开销。我可以让多个线程共享同一个数据库连接并并行执行多个 SQL 查询吗?

1 个答案:

答案 0 :(得分:0)

理论上,JDBC 连接要求是线程安全的,但在实践中存在问题,原因有两个:

  1. 并非所有驱动程序实际上都是线程安全的,甚至声称线程安全的驱动程序也可能没有针对此线程安全性进行健壮的测试,因为从多个线程并发使用连接是不推荐和不常见的。

  2. 从多个线程并发使用单个连接会带来各种额外的协调问题:一个线程提交或回滚,或者从自动提交假切换到自动提交真,会破坏所有其他线程的事情在同一连接上:工作丢失,或活动结果集突然关闭(例如,由于提交,或 JDBC 要求在自动提交中执行语句将关闭同一连接上的任何先前结果集)。

    此外,如果连接中断(或被其中一个线程关闭),这也会影响您的所有其他线程。

此外,如果驱动程序是线程安全的,那么这种线程安全通常是通过大量同步块或其他形式的互斥来实现的。这会严重影响使用单独连接的性能,因为其他线程将不得不相互等待。

为每个线程使用一个连接要简单得多,因为它将一个线程的工作与所有其他线程隔离开来。此外,由于没有对连接的竞争访问,它通常会表现得更好。如果您担心多个连接的设置成本,那么您应该做两件事:

  1. 使用连接池,可让您轻松重复使用连接。
  2. 使用大小有限的线程池来执行实际工作。

这样做有很多好处:可以向线程池提交单独的工作单元;工作单元从池中获取一个连接,并在完成时返回它(通过关闭连接)。以这种方式使用连接池还允许您轻松替换断开的连接,而无需在应用程序代码本身中处理此问题(除了可能对断开连接的任务进行重试),并最终同时使用连接池和线程池允许您尝试调整两者的大小,以了解为您的应用程序提供最佳吞吐量的合适大小。