Java中的PostgreSQL持久连接(使用JDBC)

时间:2017-05-23 14:34:30

标签: java postgresql jdbc

我正在设置一个数据记录器,它从一个安静的Web服务(来自生产设施上安装的PLC)轮询数据,我需要在PostgreSQL数据库上编写它。

我通常需要每隔30秒从5台不同的机器读取数据,每周24 / 24h和6天。如果我决定在查询后每次关闭连接,那么每天大约会有15.000个连接到数据库的连接。我假设所有5台机器都会在不同时间读取,但当然我们可以将它减少到3.000次查询,如果我决定同时阅读所有这些机器。

使用PostgreSQL实现持久连接的最佳方法是什么?我怀疑是创建一个数据库" handler"上课并返回"连接"要使用的对象可能会受到超时或错误的影响(当连接自行关闭时,我无法记录任何数据)。

2 个答案:

答案 0 :(得分:1)

共享连接的最佳方式是连接池,例如DBCP

如果你有不同的机器连接到数据库,那就困难一点。 我会在不同的机器或其中一台机器上设置服务。例如,通过REST或其他可能的接口。

最后确保检查你的PostgreSQL配置。你会在postgres wiki中找到一个好的guide

答案 1 :(得分:1)

保持连接打开

您似乎在说,您有五个JDBC客户端,每个客户端需要进行一次查询,或者每半天每半分钟写一次,每周六天。如果是这种情况,我认为根本不需要断开连接。让每个JDBC客户端保持一个开放的连接。

为什么你认为有必要关闭半分钟通话之间的联系?如果还有其他因素需要考虑,请编辑您的问题以澄清。

确保测试JDBC连接,因为它可能会因网络中断或重新启动Postgres服务器而丢失。如果连接失败,请打开另一个。

您可以无限期地维护应用与Postgres服务器之间的连接。请记住两件事:txn超时和网络的脆弱性。

交易超时

每个客户connection has default settings。其中之一是idle_in_transaction_session_timeout (integer)。如果您将事务保留的时间超过此限制,则会回滚事务并关闭您的连接(会话)。

如果您知道您将长时间打开交易,则可以禁用超时功能。一般不推荐。可能与您的用例无关。如果你完全使用交易,你的描述听起来很简短。

引用the documentation

  

idle_in_transaction_session_timeout (integer)

     

使用空闲时间超过指定持续时间(以毫秒为单位)的打开事务终止任何会话。这允许释放该会话持有的任何锁,并重新使用连接槽;它还允许仅对此事务可见的元组进行清理。有关此内容的更多详细信息,请参见第24.1节。

     

默认值0禁用此功能。

网络脆弱性

网络连接本质上是脆弱的。经验不足的程序员倾向于不了解这一挑战,因为开发环境往往比实际部署环境更可靠。

程序员在使用网络连接时必须格外小心。请参阅fallacies of distributed computing。您必须假设发生网络中断和数据库连接失败。每次工作时都要测试数据库连接的有效性。捕获JDBC驱动程序抛出的异常。适当时使用事务来保护数据的完整性。这是交易发明的主要原因:我们期待失败。

换句话说,你在问题中没有提到“持久连接”这样的事情。只有连接。无论是开放50毫秒还是50天都是无关紧要的:所有连接都随时都有失败的风险。所以,再次期待失败

确保在开发测试周期中测试网络故障。有很多高科技的方法可以做到这一点。我的最爱之一是:在运行时拔下以太网线。

如果可行(足够的内核,足够的RAM,足够的稳定性),请考虑在同一个盒子上部署您的应用程序和Postgres服务器。应用程序和数据库之间的本地连接将比跨机器的分布式(联网)更加可靠(和更快)。但是其他部署问题可能会决定单独的机器。系统管理就是权衡利弊。

线程

如果在应用中使用线程,请确保它们不共享JDBC连接。每个线程都应该使用自己的连接。

你提到了一个"数据库处理程序"到"获得连接"。不确定你的意思。通常,我建议使用DataSource对象,您可以在其中调用getConnection。您的JDBC驱动程序应提供实现。

不要使用连接池

通常建议使用连接池来进行数据库工作,有时候经常会在没有正确考虑优缺点的情况下反复建议连接池。连接池带来了自己的风险和复杂性。

当有许多客户端对数据库进行间歇性调用时,连接池最有用。您的情况正好相反,很少有客户经常拨打数据库。所以我想说连接池是禁忌的。