【问题标题】:Oracle JDBC connection timed out issueOracle JDBC 连接超时问题
【发布时间】:2017-01-19 15:11:22
【问题描述】:

我有一个 Web 应用程序的生产场景,当提交表单时,数据通过 JDBC 存储在 Oracle DB 的 3 个表中。有时,当应用程序尝试通过 Java 代码连接到 Oracle DB 时,我会在日志中看到连接超时错误。这是间歇性的。

以下是例外:

SQL exception while storing data in table
java.sql.SQLRecoverableException: IO Error: Connection timed out

大多数情况下,Web 应用程序能够连接到数据库并在其中插入值,但有时我会遇到超时错误并且无法在其中插入数据。我不确定为什么会出现这个间歇性问题。当我检查应用程序中的连接池配置时,我注意到以下几点:

  • 池大小(此池可以打开的最大连接数):10

  • 池等待(如果所有池连接都在使用中,则在引发异常之前的最大等待时间,以毫秒为单位):1000

由于池大小仅为 10,如果有多个用户尝试连接到数据库,是否会出现此连接超时问题?

此外,由于数据插入发生在 3 个表中,我们只在一个连接本身中进行整个插入。我们不会为每个单独的表打开每个数据库连接。

注意:此应用程序部署在 AEM(内容管理系统)服务器上,连接池配置由它们提供。

更新:我尝试在连接池中设置验证查询,但仍然收到连接超时错误。我不确定连接池是否检查了验证查询。我附上了上面的连接池供参考。

【问题讨论】:

  • 您能说明一下池是如何配置的吗?喜欢配置文件或界面只是为了看看有哪些选项可用?
  • 如果您要与多个用户执行复杂的操作,等待一秒钟并不是很长的时间。

标签: java oracle jdbc aem


【解决方案1】:

我会尝试两件事:

  • 尝试设置一个验证查询,以便每次池租用一个连接时,您都可以确定它实际上是可用的。 select 1 from dual 应该可以工作。最近不需要的 JDBC 驱动程序,但您可以试一试。

  • 估计表单的并发性。根据您在 DB 上工作的复杂性,一个 10 个连接池并不算太小。看来您正在保存一个表单,所以它不应该那么复杂。您预计每天有多少用户?那么,在高峰期,您希望有多少用户同时使用该表单?一个有 10 个连接的池通常会非常快地租用和检索连接,因此它每秒可以处理多个事务。如果您期望更多,请稍微增加大小(超过 25-30 实际上会降低数据库性能,因为更多查询会争夺那里的资源)。

  • 如果似乎没有任何效果,最好检查一下数据库上发生了什么。如果可能,使用 Enterprise Manager 查看在这三个表上执行操作时是否存在闩锁。

【讨论】:

  • 感谢您的建议!!我还看到了一个名为 conn.isValid(0) 或 conn.isClosed() 的方法。我也可以使用这些方法来检查连接是否关闭?如果 conn 无效,那么我将再次调用 conn.getConnection()。
  • 我在连接池中使用了验证查询,但仍然出现超时错误。连接池的 PFA
【解决方案2】:

我从编程的角度给出这个答案。这个问题有多种可能性。这些是以下内容,我已经为它添加了适当的解决方案。当连接超时发生时,意味着您的新线程在上述时间内没有获得数据库访问权限,这是由于:

  • 可能性一:未关闭连接,您的应用程序中应该有连接泄漏解决方案
    你需要确保这个东西,并且需要检查这个泄漏并在使用后关闭连接。

  • 可能性二:大交易解决方案

    • 我。这些插入是否同步,如果是,请非常小心地使用它。在块级别而不是方法级别使用它。并且您的同步块大小应尽可能小。

      如果我们有大的同步块,我们会提供连接,但它会处于等待状态,因为这个同步块需要太多时间来执行。所以其他线程等待时间增加。假设我们有 100 个用户,每个用户有 100 个线程用于该操作。第一个正在执行,它需要很长时间。和其他人正在等待。所以可能会出现第 80、90 等线程抛出超时的情况。对于某些线程,会出现此问题。

      所以你必须减少同步块的大小。

    • 二。对于这种情况,还要检查交易是否很大,如果可能,请尝试将交易分成更小的交易:-
      举个例子,一个插入一个小事务。对于第二个其他小交易,像这样。这三个小事务就完成了操作。
  • 可能性三:应用程序可用性过高,池大小不够解决方案
    需要增加池大小。 (使用后正确关闭所有连接即可适用)

【讨论】:

    【解决方案3】:

    在这种情况下可以使用Java Executor服务。一个线程一个连接,所有异步。一旦事务完成,将连接释放回池。这样就可以摆脱这个超时问题。

    如果一个连接正在向3个表中插入数据,而其他试图建立连接的线程正在等待,则必然会发生超时。

    【讨论】:

      猜你喜欢
      • 2014-09-24
      • 1970-01-01
      • 2011-01-20
      • 2017-02-07
      • 2014-04-15
      • 1970-01-01
      • 2010-10-03
      • 2023-03-27
      相关资源
      最近更新 更多