Java Oracle JDBC连接超时问题

Java Oracle JDBC连接超时问题,java,oracle,jdbc,aem,Java,Oracle,Jdbc,Aem,我有一个web应用程序的生产场景,当提交表单时,数据通过JDBC存储在Oracle DB中的3个表中。有时,当应用程序试图通过Java代码连接到Oracle DB时,我会在日志中看到连接超时错误。这是间歇性的 以下是例外情况: SQL exception while storing data in table java.sql.SQLRecoverableException: IO Error: Connection timed out 大多数情况下,web应用程序能够连接到数据库并在其中插入

我有一个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 Executor服务。一个线程一个连接,所有异步。一旦事务完成,将连接释放回连接池。这样,您就可以摆脱此超时问题


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

我会尝试两种方法:

  • 请尝试设置验证查询,以便每次池租用连接时,您都可以确定它实际上是可用的<代码>从双重选择中选择1应起作用。在最新的JDBC驱动程序上,这不应该是必需的,但您可以试一试

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

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


    • 我从编程的角度给出了这个答案。这个问题有多种可能性。以下是我为其添加的适当解决方案。当连接超时时,意味着您的新线程无法在上述时间内访问数据库,原因是:

      • 可能性一:未关闭连接,应用程序解决方案中的某个地方应该存在连接泄漏
        您需要确保这一点,需要检查泄漏情况,并在使用后关闭连接

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

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

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

          所以您必须减小同步块的大小

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


      您能说明池是如何配置的吗?像配置文件或界面一样,只是为了看看有哪些选项可用?如果您正在对多个用户执行复杂的操作,一秒钟的等待时间不会太长。谢谢您的建议!!我还看到了一个名为conn.isValid(0)或conn.isClosed()的方法。我是否可以使用这些方法检查连接是否未关闭?如果conn无效,那么我将再次调用conn.getConnection()。我在连接池中使用了验证查询,但仍然得到超时错误。连接池的PFA