java - 如何保持 jdbc 到 postgres 的存活

标签 java postgresql jdbc timeout

所以我已经跟踪了一两天的错误,它发生在我几乎无法控制的远程服务器上。我的代码的来龙去脉是,我向我们的 UI 团队提供了一个 jar 文件,它包装了 postgres 并为用户导入的数据提供存储。由于多种原因,导入过程非常缓慢,其中之一是用户正在导入不可预测的大量数据(我们无法真正减少)。这导致了大量的超时问题。

经过一些初步调查,我已将问题缩小到 jdbc 到 postgres 数据库超时。我在本地测试设置上复制这个时遇到了很多麻烦,但最终通过将连接属性的“socketTimeout”减少到 10 秒(连接上的每次调用之间的间隔超过 10 秒)设法做到了。

我现在的问题是,保持这种状态的最佳方式是什么?我已将“tcpKeepAlive”设置为 true,但这似乎没有效果,我是否需要手动轮询连接或其他方式?从我读过的内容来看,我假设轮询是自动的,并且由操作系统控制。如果这是真的,我真的无法控制运行环境中的操作系统设置,处理这个问题的最佳方法是什么?

我正在考虑每次使用时都测试连接,如果超时,我就创建一个新的。这是正确的做法还是有更好的方法来保持连接?我刚刚看过这篇文章,人们建议您应该在每个查询中打开和关闭连接: When my app loses connection, how should I recover it?

在我的情况下,我有一系列在单个线程上发生的顺序插入,如果一个失败,它们都会失败。为此,我使用了交易:

m_Connection.setAutoCommit(false); 
m_TransactionSave = m_Connection.setSavepoint();

// Do something

m_Connection.commit(); 
m_TransactionSave = null; 
m_Connection.setAutoCommit(true);

如果我继续重新连接,或者使用像 PGBouncer 这样的连接池(就像有人在评论中建议的那样),我如何在它们之间持久保存这个事务?

最佳答案

可以使用保持 Activity 设置配置与 PostGres 的 JDBC 连接。此处针对此功能提出了一个问题:JDBC keep alive issue .此外,还有 parameter help page .

根据上面的注释,您可以将以下内容添加到 JDBC 连接的连接参数中:

tcpKeepAlive=true;

减少 socketTimeout 会使事情变得更糟,而不是更好。 socketTimeout 是连接在预期数据到达但实际没有到达时应等待多长时间的度量。使它更长,而不是更短是我的直觉。

您是否可能正在使用 PGBouncer ?如果没有 Activity ,该进程将主动终止来自服务器端的连接。

最后,如果您在 Linux 上运行,您可以更改 TCP 保持 Activity 设置:keep alive settings .我确信 Windows 也存在类似的东西。

关于java - 如何保持 jdbc 到 postgres 的存活,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26142526/

相关文章:

java - 如何为 PointPlacemarks 添加图层?

java将列表字符串写入csv文件

postgresql - 如何计算每个学生的平均分

ruby-on-rails - 如何根据模型属性在索引 View 上设置复选框?

java - 如何访问数据库 native java.sql.Connection?

java - 如何获得 Child 类?

java - 小行星类游戏中的正确运动

postgresql - Postgres 全文搜索未返回预期结果

java - 如何使用jdbc在mysql中动态传递表名?

java - 如何使用联合运算符连接 sql 查询