Java中有多少个JDBC连接?

时间:2009-01-23 03:09:15

标签: java performance jdbc database-connection

我有一个由大约15种方法组成的Java程序。并且,在程序的执行期间非常频繁地调用这些方法。目前,我正在每个方法中创建一个新连接并在其上调用语句(数据库在网络上的另一台机器上设置)。

我想知道的是:我应该在main方法中只创建一个连接,并将其作为参数传递给需要连接对象的所有方法,因为它会显着减少程序中连接对象的数量,而不是在每种方法中频繁地创建和关闭连接。

我怀疑我没有在当前设计中非常有效地使用资源,并且考虑到该程序将来可能会增长很多,因此还有很大的改进余地。

5 个答案:

答案 0 :(得分:22)

是的,您应该考虑重新使用连接,而不是每次都创建一个新连接。通常的程序是:

  • 猜测数据库可以合理处理多少个并发连接(例如,在数据库计算机上以每个CPU 2或3开始,直到您发现它太少或太多 - 它将倾向于依赖关于你的查询的磁盘限制方式)
  • 创建这么多连接的:本质上是一个类,您可以在每个方法的开头请求“下一个空闲连接”,然后在最后“回传”到池中每种方法
  • 你的getFreeConnection()方法需要返回一个空闲连接(如果有),否则(1)创建一个新连接,最多为你决定允许的最大连接数,或者(2)如果最大已经创建,等待一个人免费
  • 我建议使用Semaphore类来管理连接;我实际上在managing a resource pool with a Semaphore的网站上有一篇简短的文章,其中有一个例子,我认为你可以适应你的目的

一些实际考虑因素:

  • 为了获得最佳性能,您需要小心在您实际不使用它来运行查询时不要“占用”连接。如果您从池中获取一次连接然后将其传递给各种方法,则需要确保不会意外地执行此操作。
  • 别忘了将您的连接返回游泳池! (尝试/最后是你的朋友......)
  • 在许多系统上,无法永久保持连接打开:操作系统将在最长时间后关闭它们。因此,在“返回与池连接”方法中,您需要考虑已经存在很长时间的'退休'连接(构建一些记忆机制,例如通过围绕实际JDBC Connection对象的包装器对象,可用于存储此类指标)
  • 您可能需要考虑使用预准备好的陈述。
  • 随着时间的推移,您可能需要调整连接池大小

答案 1 :(得分:9)

您可以传递连接,也可以更好地使用Jakarta数据库连接池等功能。 http://commons.apache.org/dbcp/

答案 2 :(得分:8)

您应该使用连接池。

这样你就可以要求连接并在完成后将其释放并将其返回池中

如果另一个线程想要一个新连接并且正在使用一个新连接,则可以创建一个新连接。如果没有其他线程正在使用连接,则可以重复使用它。

通过这种方式,您可以以某种方式离开您的应用程序(并且不会四处传递连接)并仍然正确使用资源。

不幸的是,第一类ConnectionPools在独立应用程序中并不是很容易使用(它们是应用程序服务器中的默认设置)可能是一个微容器(如Sping)或一个好的框架(如Hibernate)可以让你使用它。

虽然从头开始编写代码并不难。

:)

This google search将帮助您找到有关如何使用其中的更多信息。

浏览

答案 3 :(得分:3)

许多JDBC驱动程序会为您执行连接池,因此在这种情况下执行其他池的优势很小。我建议您查看JDBC驱动程序的文档。

连接池的另一种方法是

  • 通过同步访问为所有数据库访问建立一个连接。这不允许并发,但非常简单。
  • 将连接存储在ThreadLocal变量中(覆盖initialValue())如果有少量固定线程,这种方法很有效。

否则,我建议使用连接池。

答案 4 :(得分:1)

如果您的应用程序是单线程的,或者从单个线程执行所有数据库操作,则可以使用单个连接。假设您出于任何其他原因不需要多个连接,这将是迄今为止最简单的实现。

根据您的驱动程序,在线程之间共享连接也是可行的 - 如果您相信您的驱动程序不会对其线程安全性撒谎,这也可以。有关详细信息,请参阅驱动程序文档。

通常,“Connection”下面的对象无法安全地从多个线程中使用,因此通常不建议在线程之间共享ResultSet,Statement对象等 - 到目前为止,最好的策略是在创建它们的同一线程中使用它们;这通常很容易,因为这些物品一般不会保存太久。