我有一个生产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(内容管理系统)服务器上,连接池配置由它们提供。
更新:我尝试在连接池中设置验证查询,但我仍然收到连接超时错误。我不确定连接池是否已检查验证查询。我已将上面的连接池附加以供参考。
答案 0 :(得分:1)
我会尝试两件事:
尝试设置验证查询,以便每次池租用连接时,您确定它实际可用。 select 1 from dual
应该有效。在最近的JDBC驱动程序中,这些驱动程序不应该被要求,但您可以试一试。
估算表单的并发性。根据您在DB上工作的复杂程度,10个连接池不会太小。看来你正在保存一个表格,所以它不应该那么复杂。您期望每天有多少用户?那么,在高峰时间,您希望同时使用该表单的用户数量是多少? 10个连接池通常可以非常快速地租用和检索连接,因此它可以每秒处理多个事务。如果您期望更多,请稍微增加 的大小(超过25-30实际上会降低数据库性能,因为有更多查询在那里竞争资源)。
如果似乎没有任何效果,最好检查数据库上发生了什么。如果可能,使用Enterprise Manager在这三个表上执行操作时查看是否存在锁存器。
答案 1 :(得分:0)
在这种情况下你可以使用Java Executor服务。一个线程一个连接,所有异步。一旦完成事务,将连接释放回池。这样,你可以摆脱这个超时问题。
如果一个连接在3个表中插入数据并且其他尝试建立连接的线程正在等待,则必然会发生超时。
答案 2 :(得分:0)
我从编程的角度给出了这个答案。这个问题有多种可能性。这些是以下,我已经为它添加了适当的解决方案。当发生连接超时时,意味着您的新线程在上述时间内没有获得数据库访问权限,这是由于:
可能性I:未关闭连接,应用程序中的某处应该存在连接泄漏解决方案
您需要确保这一点,并需要检查此泄漏并在使用后关闭连接。
可能性II:大交易解决方案
我。这些插入是否同步,如果是这样,那么请非常小心地使用它。在块级而非方法级使用它。并且您的同步块大小应尽可能小。
如果我们有大的同步块,我们会给出连接,但它会处于等待状态,因为这个同步块需要太多时间来执行。所以其他线程等待时间增加。假设我们有100个用户,每个用户有100个线程用于该操作。第一个是执行,它需要很长时间。和其他人在等待。因此可能存在第80个第90个等线程抛出超时的情况。对于某些线程,会出现此问题。
因此,您必须减小同步块的大小。
可能性III:如果应用程序的可用性太高,则池大小不够解决方案
需要增加池大小。 (如果您在使用后正确关闭所有连接,则适用)