0

我们在使用 JDBC 连接到 SQL Server 数据库的 Tomcat 6 中运行的 Java Web 应用程序遇到问题。

在几次请求之后,应用程序服务器死掉了,并且在日志文件中我们发现了与数据库连接失败相关的异常。

我们现在没有使用任何连接池,而是使用标准的 JDBC/ODBC/ADO 驱动程序桥连接到 SQL Server。

我们是否应该考虑使用连接池来消除问题?

另外,我们是否应该将驱动程序更改为类似 jTDS 的东西?

4

3 回答 3

1

我肯定会试试 jTDS。我过去在 Tomcat 5.5 中使用过它,没有任何问题。作为调试步骤,这似乎是一个相对快速、影响较小的更改。我想你会发现它更快更稳定。它还具有开源的优势。

从长远来看,我认为您会出于性能原因考虑连接池。当你这样做时,我建议你看看c3p0。我认为它比 Tomcat 的内置池选项更灵活,而且我通常更喜欢“容器外”解决方案,以便将来切换容器时不那么痛苦。

于 2009-01-09T16:43:15.883 回答
1

真的很难说,因为你提供的关于实际失败的信息太少了:

在几次请求之后,应用程序服务器死掉了,并且在日志文件中我们发现了与数据库连接失败相关的异常。

你能告诉我们:

  • 你看到的错误到底是什么
  • 给我们一个代码的小例子,您可以在其中连接和服务您的一个请求
  • 是在一致数量的事务之后失败,还是看起来是随机的

我已经编写了很多与数据库相关的 java 代码(几乎我所有的代码都是与数据库相关的),并使用了 MS 驱动程序、jdt 驱动程序和来自 jnetDirect 的驱动程序。

我敢肯定,如果您向我们提供更多详细信息,我们可以为您提供帮助。

于 2009-01-10T00:31:35.907 回答
1

如果您没有关闭 JDBC 连接,那么这是正确的行为。

当您使用完每个 JDBC 资源以及您使用它获得的其他 JDBC 资源时,您必须调用它的 close() 方法。

这适用于 Connection、Statement/PreparedStatement/CallableStatement、ResultSet 等。

如果你没有做到这一点,对于初学者来说,你将在 SQL 服务器上囤积潜在的巨大且可能非常有限的资源。

最终,连接将不会被授予,执行获取查询并返回结果将失败或挂起。

如果您未将 autoCommit 属性设置为 true,则在每个事务结束时未能 commit() 或 rollback() 时,您还可能会注意到 INSERT/UPDATE/DELETE 语句挂起。

我所看到的是,如果您将上面提到的严格应用到您的 JDBC 客户端代码中,那么 JDBC 和您的 SQL 服务器将非常顺利地工作。如果你写废话,那么一切都会像废话一样。

许多人编写 JDBC 调用时期望通过调用 close() 来释放每个东西,因为这很无聊,并且应用程序和服务器在他们忽略它时不会立即失败。

确实如此,但是那些程序员编写了他们的程序来与他们的服务器玩“墙上的 99 瓶啤酒”。

资源将耗尽,请求往往会导致以下一种或多种情况发生:连接请求立即失败,SQL 语句立即失败或永远挂起,或者直到某个可怕的冗长事务超时计时器到期,等等。

因此,解决这些类型的 SQL 问题的最快方法不是责怪 SQL 服务器、应用程序服务器、Web 容器、JDBC 驱动程序,也不能责怪 Java 垃圾收集器中嵌入的令人失望的人工智能。

解决这些问题的最快方法是射杀在您的应用程序中编写 JDBC 调用的人,该调用使用 Nerf dart 与您的 SQL 服务器通信。当他说:“你这样做是为了什么……?!” 只需指向这篇文章并告诉他阅读即可。(切记不要拍他的眼睛、他手里的东西、可能危险/易碎的东西等)

至于连接池解决您的问题......不。抱歉,连接池只是通过将预先分配的、可能是回收的连接交给应用程序来加速获取应用程序中的连接的调用。

牙仙把钱放在你的枕头下,复活节兔子把鸡蛋和糖果放在你的灌木丛下,圣诞老人把礼物放在你的树下。但是,很抱歉打破了您的幻想——SQL 服务器和 JDBC 驱动程序不会关闭所有内容,因为您“忘记”了关闭您自己分配的所有内容。

于 2009-01-11T00:52:49.917 回答