所以我已经跟踪一个bug一两天了,这个bug发生在我几乎无法控制的远程服务器上。我的代码的来龙去脉是,我向UI团队提供了一个jar文件,该文件封装postgres并为用户导入的数据提供存储。由于多种原因,导入过程非常缓慢,其中之一是用户正在导入不可预测的大量数据(我们无法真正减少这些数据)。这导致了大量的超时问题。
经过一些初步调查,我将其缩小到jdbc到postgres数据库超时。我在本地测试设置中复制这一点时遇到了很多困难,但最终还是成功地将连接属性的"socketTimeout"减少到了10秒(在连接上进行的每次调用之间都有超过10秒的时间)。
我现在的问题是,保持这种状态的最佳方式是什么?我已经将"tcpKeepAlive"设置为true,但这似乎没有效果,我需要手动轮询连接吗?根据我所读到的内容,我假设轮询是自动的,并且由操作系统控制。如果这是真的,我真的无法控制运行环境中的操作系统设置,那么处理这种情况的最佳方法是什么?
我考虑在每次使用连接时测试它,如果它超时,我只会创建一个新的连接。这是正确的做法吗?还是有更好的方法来保持连接?我刚刚看了一下这篇文章,人们建议你应该根据每个查询打开和关闭连接:当我的应用程序失去连接时,我应该如何恢复?
在我的情况下,我有一系列在单个线程上进行的顺序插入,如果单个线程失败,它们都会失败。为了实现这一点,我使用了交易:
m_Connection.setAutoCommit(false);
m_TransactionSave = m_Connection.setSavepoint();
// Do something
m_Connection.commit();
m_TransactionSave = null;
m_Connection.setAutoCommit(true);
如果我继续重新连接,或者使用像PGBouncer这样的连接池(就像有人在评论中建议的那样),我该如何在他们之间保持此事务?
到PostGres的JDBC连接可以使用保持活动设置进行配置。这里针对这个功能提出了一个问题:JDBC保持活动问题。此外,还有参数帮助页面。
从上面的注释中,您可以将以下内容添加到JDBC连接的连接参数中:
tcpKeepAlive=true;
减少socketTimeout应该会使情况变得更糟,而不是更好。socketTimeout是衡量连接在期望数据到达但没有到达时应该等待多长时间的指标。让它变长而不是变短是我的本能。
你可能正在使用PGBouncer吗?如果没有活动,该进程将主动终止来自服务器端的连接。
最后,如果您在Linux上运行,您可以使用:keep-alive settings更改TCP保持活动设置。我确信Windows也存在类似的情况。