2009-01-23 65 views
16

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

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

我怀疑我现在的设计并不是非常有效地使用资源,并且考虑到这个程序未来可能会增长很多,还有很大的改进余地。

回答

21

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

  • 猜测您的数据库可以合理处理多少个同时连接(例如,从数据库机器上的每个CPU开始2或3,直到你发现这太少或太多 - 它往往取决于你的查询是如何磁盘绑定的)
  • 创建一个这个很多连接:本质上是一个类,您可以在每个方法的开始处要求“下一个空闲连接”,然后在每个方法结束时“传回”池中的数据。您的getFreeConnection()方法需要返回一个(1)创建一个新的连接,直到您决定允许的最大连接数,或者(2)如果已经创建了最大连接数,请等待一个成为免费连接
  • 我建议使用Semaphore类来管理连接;其实,我在我的网站很短的文章managing a resource pool with a Semaphore有一个例子,我想你可以适应你的目的

一对夫妇的实际考虑:

  • 为了获得最佳性能,你必须要小心当您没有实际使用它来运行查询时,不要“连接”连接。如果您从游泳池中连接一次,然后将其传递给各种方法,则需要确保您不会意外地执行此操作。
  • 不要忘了把你的连接返回到游泳池! (尝试/最后是你的朋友在这里...)
  • 在许多系统上,你的无法保持连接'永远'打开:O/S会在一些最大时间后关闭它们。因此,在'返回连接池'方法中,您需要考虑长期存在的'退休'连接(构建用于记忆的某种机制,例如通过具有包装对象围绕一个实际的JDBC连接对象,您可以使用这个对象来存储诸如此类的指标)
  • 您可能需要考虑使用预准备语句。
  • 随着时间的推移,你可能需要调整连接池大小
+0

您能否详细说明Prepared Statements如何在这里提供帮助? – Epitaph 2009-01-28 00:26:04

8

您应该为此使用连接池。

这样,你可以问的连接,并释放它,当你完成它,并返回到池中

如果另一个线程想要一个新的连接,以及一个在使用中,一个新的可能创建。如果没有其他线程正在使用连接,则可以重复使用该连接。

通过这种方式,您可以以某种方式将应用程序保持原样(而不是全部传递连接),并仍然正确使用资源。

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

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

:)

This google search将帮助你找到更多有关如何使用一个。

滑过

+0

如果不考虑连接的“退休”为什么我们需要多个连接?一个单一的连接可以在任何地方使用rit;因为声明objs总是不同?当我们在应用程序中需要多个连接时? – 2012-09-17 18:11:10

0

如果您的应用程序是单线程的,或不从单个线程的所有数据库操作,这是确定使用单连接。假设您因任何其他原因不需要多个连接,这将是最简单的实现。

根据你的驱动程序,在线程之间共享连接也是可行的 - 如果你相信你的驱动程序不要说谎它的线程安全性,这也可以。有关更多信息,请参阅驱动程序文档

通常,“Connection”下面的对象不能安全地在多个线程中使用,因此在线程之间共享ResultSet,Statement对象通常是不可取的 - 迄今为止最好的策略是在创建它们的同一个线程中使用它们;这通常很容易,因为这些对象通常不会保存太久。

3

许多JDBC驱动程序为您执行连接池,因此在此情况下执行额外的池操作几乎没有优势。我建议你检查你的JDBC驱动程序的文档。

另一种方法来连接池是

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

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