2014-10-01 25 views
2

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

经过一些初步调查,我已经缩小到jdbc到postgres数据库超时。我在我的本地测试设置上复制了这个问题时遇到了很多麻烦,但最终设法通过将连接属性的'socketTimeout'减少到10s(在连接上进行的每次调用之间有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(好像有人在评论中所建议的),我该如何坚持跨越他们这个交易?

回答

3

到PostGres的JDBC连接可以配置保持活动设置。这个功能在这里发生了一个问题:JDBC keep alive issue。此外,还有parameter help page

从那个音符,你可以添加以下为JDBC连接的连接参数:

tcpKeepAlive=true; 

减小了socketTimeout应使事情变得更糟,而不是更好。 socketTimeout是连接等待数据到达时等待多长时间的一种度量,但它没有。做更长,不会更短,这是我的本能。

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

最后,如果您在Linux上运行,则可以使用:keep alive settings更改TCP保持活动设置。我相信Windows有类似的东西存在。

+0

感谢您的回复。我会研究它。我如上所述,我已经使用tcpKeepAlive = true;这似乎没有做任何事情(我假设,因为我没有改变我的本地机器上的操作系统设置,这是基于Windows)。至于超时,正如我所说,我故意让我的本地机器更糟糕,以验证它是一个超时问题。在实时服务器上,超时将是合理的。我目前没有使用PGBouncer,我不熟悉使用连接池,但是我担心它会如何与我的交易进行交互。 – Andy 2014-10-01 14:00:24