【问题标题】:Using JNDI for Database connections使用 JNDI 进行数据库连接
【发布时间】:2009-11-24 21:53:47
【问题描述】:

这听起来像是一个菜鸟问题,但这是我第一次涉足数据库领域。
here我得到了信息

最有效的实施方式 服务器和服务器之间的通信 database就是建立一个数据库 连接池。创建一个新的 每个客户端请求的连接都可以 非常耗时,尤其是对于 不断收到的应用程序 大量的请求。

本教程使用 JNDI 数据源。

我的应用程序也类似(但我不会使用 Tomcat,只使用套接字),我的服务器会从多个客户端获取请求,但我不明白为什么要使用 JNDI 数据源,为什么不能服务器与数据库保持一个开放的连接,当客户端请求到达时,它将处理请求并将数据提供给客户端。

在最坏的情况下,如果我需要 JNDI,我该如何使用我的服务器应用程序来实现它?

【问题讨论】:

    标签: java database jdbc jndi


    【解决方案1】:

    因此,它是一个客户端应用程序?应用程序和数据库通常使用DriverManager#getConnection() 获得的连接进行通信?如果是这样,那么您不一定需要 JNDI 来使连接池工作。单独的连接池框架已经足够了。例如C3P0Apache Commons DBCP(我推荐C3P0;DBCP 是单线程的)。只需将DriverManager#getConnection() 替换为它即可。

    编辑:回复您的 cmets:

    服务器将与数据库通信,客户端连接到服务器,所以我不知道是否将其称为客户端应用程序。

    我的意思是,一个普通的 Java 应用程序,它不在 Java EE 容器中运行。帕斯卡的措辞更好。

    实际上我对连接池的工作原理有点困惑,每个连接是否都在自己的线程中运行?是否有任何文档/书籍可以帮助我更好地理解这些概念相对于非池连接?

    首先,连接池打开一个连接并将其保持打开状态,直到配置的超时。连接池用自己的实现包装/decorates 连接。连接池可以同时打开并保持配置数量的连接。当您拨打getConnection() 时,它会立即为您提供一个已经打开的连接。当您在连接上调用close() 时,它会将连接放回池中以供将来请求。因此,这意味着您仍然必须以通常的方式编写 JDBC 代码:在 最短 可能的范围内获取并关闭 ConnectionStatementResultSet。在finally 块中将它们全部关闭。如果您的 JDBC 代码已经写得很好,实际上只有 DriverManager#getConnection() 需要被替换。因为你应该在同一个方法块中打开和关闭Connection,它通常会在同一个线程中运行。连接池会担心Connection 不会同时被其他线程获取,直到您的代码在Connection 上调用close()

    您可以找到here 一篇不错的文章,了解连接池是如何在幕后工作的(注意:不要将它用于生产,也不要进一步自行开发,这只是为了了解整个想法)。对于实际工作,请使用现有的彻底开发且强大的连接池框架。

    【讨论】:

    • 服务器将与数据库通信,客户端连接到服务器,所以我不知道是否将其称为客户端应用程序。是的,代码的服务器部分正在使用 DriverManager.getConnection(),感谢 C3P0 链接。
    • 感谢清晰、简洁的解释,我使用 DriverManager 编写了一些示例代码,但我保持连接打开。我的客户正在使用套接字连接到服务器并将保持连接状态。每个客户端都在自己的读/写线程中运行,因此如果服务器想要传递数据,它只会从数据库(来自已经打开的连接)询问数据并将其传递给所述客户端。这是正确的方法还是我应该尽快关闭连接?
    • 通常的做法是,您应该在 finally 块中关闭连接,以避免在您打开多个连接和/或数据库时间的情况下资源泄漏和/或潜在的应用程序崩溃出连接。要提高连接性能,最好的方法是使用连接池。只需确保您没有配置连接池的超时时间(即保持连接打开的时间)长于数据库自己的连接超时时间。
    【解决方案2】:

    我的应用程序也类似(但我不会使用 Tomcat,只使用套接字),我的服务器会从多个客户端获取请求,但我不明白为什么要使用 JNDI 数据源,为什么不能服务器与数据库保持一个开放的连接,当客户端请求到达时,它将处理请求并将数据提供给客户端。

    嗯,你可以。但是,如果您有多个客户端并且必须处理并发请求怎么办?当然,您可以为每个客户端保持一个打开的连接,但这并不能很好地扩展(这在您的上下文中可能不是问题)。尽管如此,解决这个问题的传统方法是使用连接池(并从额外的服务中受益,例如连接验证、连接更新)并使用它来“按需”获取连接。

    如果您不在 J2EE 容器上下文中,请使用独立的连接池实现,例如 c3p0(首选 c3p0 而不是 DBCP,后者被认为已过时且在负载下不太健壮)并忘记 JNDI(这只是在 J2EE 容器中运行时获取连接池句柄的标准方法。

    查看 c3p0 的 documentation 了解更多详细信息和代码示例,非常清楚。

    【讨论】:

    • 我不知道 JNDI 仅用于 J2EE 容器的上下文中,感谢您注意到这一点以及 c3p0 和 DBCP 链接。
    • 其实我对连接池的工作原理有点困惑,每个连接都运行在自己的线程中吗?是否有任何文档/书籍可以帮助我更好地理解这些概念相对于非池连接?
    【解决方案3】:

    用于数据库连接的 JNDI 解决了应用程序开发人员不是管理数据库连接的人的情况。

    因此,应用程序开发人员可以指定他们的应用程序需要多少同时连接。然后,服务器管理员将定义数据库连接池。应用程序查找池。

    应用程序和应用程序开发人员都不需要知道连接到数据库所需的凭据。此外,服务器管理员可以根据部署环境将连接池定义为不同的大小,并且应用程序不会知道这些差异。

    由于您的应用程序服务器本身,因此应用程序负责定义和管理与数据库的连接。

    【讨论】:

    • 应用开发者如何判断同时连接数。如果应用程序和应用程序开发人员不知道安全参数(凭据)在哪里指定?这些是否加载到配置文件中?
    • 对于连接计数,一种选择是猜测,然后在预期的最大生产量下进行负载测试,并监控连接使用情况。使用您在负载测试中观察到的最大值的大约 110%。或者,您可以检查应用程序的连接使用情况,并尝试根据数据库的访问方式、同时存在的客户端数量等做出有根据的猜测。凭据存储在应用程序服务器的配置中。服务器的做法不同,但它们以标准方式 JNDI 公开连接池。
    【解决方案4】:

    抛出另一个连接池的链接:BoneCP (http://jolbox.com)。基准测试表明它比 C3P0/DBCP 更快。

    附:在我的多线程测试中也没有看到 DBCP 锁定。

    【讨论】:

      猜你喜欢
      • 2011-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-19
      相关资源
      最近更新 更多