【问题标题】:Reconnecting to a postgres database after postgres restart from Java从 Java 重新启动 postgres 后重新连接到 postgres 数据库
【发布时间】:2013-06-04 19:36:33
【问题描述】:

我正在使用 postgres 9.1、org.apache.commons.dbcp.BasicDataSource(用于我的连接池)和 Java 1.7。当我重新启动我的 postgres 服务器时,我得到了像 org.postgresql.util.PSQLException: FATAL: terminating connection due to administrator command 这样的异常。

如何使连接自动重新连接到重新启动的数据库?

【问题讨论】:

  • 使用try-catch 捕获异常(检查e.getMessage() 是否实际上是服务器重新启动),然后从catch 语句或其他代码块中重新连接到数据库由它触发。
  • @Vulcan 不要检查错误信息;使用您可以从PSQLException 获取的SQLSTATE 来检查问题的原因。否则,当消息在新版本中改写或有人以不同的语言运行 Pg 时,您会遇到有趣的问题。
  • @CraigRinger 好点。我不知道PSQLException 有这样一个字段(我以前从未使用过 PSQL)。绝对应该使用它而不是消息,你是对的。
  • @Vulcan getSQLState() 是一种 SQLException 方法,是所有数据库的标准方法。 从不 解析错误消息 - 对于任何数据库,而不仅仅是 Pg。这就是 SQLState 的用途。消息类也相当标准。
  • @CraigRinger 啊,我的错。我过去只简单地使用过 JDBC。在任何情况下我都不会解析异常消息,但我不知道getSQLState()。谢谢。

标签: java postgresql jdbc apache-commons-dbcp


【解决方案1】:

DBCP 有一个连接验证查询选项 - validationQuery,根据 the docs。您可以将其设置为 SELECT 1; 之类的内容,DBCP 将在返回连接以对其进行测试之前运行它。

也就是说,您的应用确实应该处理这种情况。 SQL 查询可能由于各种原因而失败,您应该始终在具有时间回退和重试限制的重试循环中执行查询,以及一些逻辑来决定哪些异常在重试时可以恢复,哪些不能(使用 SQLState为此)。

特别是,验证受制于竞争条件,您可以在该条件下进行事件排序,例如:

  1. 验证
  2. 将连接传递给应用
  3. 服务器关闭
  4. 应用运行第一条语句

  1. 验证
  2. 将连接传递给应用
  3. 应用运行第一条语句,打开一个事务
  4. 服务器关闭
  5. 应用运行第二条语句

...所以对于您的应用来说,拥有适当的重试循环和良好的事务处理仍然很重要。

您可以从 SQLException:SQLException.getSQLState 中获取 SQLState。 PostgreSQL 的代码是in the PostgreSQL manual

【讨论】:

  • 感谢您的回答。此测试(validationQuery)会从池中删除连接吗?
  • @three-cups 是的,否则它将毫无用处。这将导致连接被丢弃并被新连接替换。您的应用仍然需要正确处理重试 - 因为您可能会在事务中途或在验证和事务开始之间关闭服务器 - 但验证是丢弃已知不良连接的有用方法。
  • 我唯一不喜欢的是,它会在从池中借用的每个连接上添加一个额外的数据库查询。我宁愿在特殊情况出现时处理它。
  • @three-cups 这也是我的观点 - 既然您无论如何都必须处理异常情况,为什么还要进行验证查询?不过,您似乎在询问如何验证连接,所以这就是我解释的内容。
【解决方案2】:

在这种特殊情况下,PostgreSQL 连接告诉您在创建连接后服务器已关闭。 DBCP 连接池的默认配置不处理这种情况。

即使您将 validationQuery 参数设置为 SELECT 1 之类的参数,它也不会被使用,除非您还设置了至少一个 testOnXXXX 参数。

我通常将 testOnCreatetestOnBorrow 都设置为 true

还要检查 DBCP 的其他默认值(在 org.apache.commons.pool2.impl.BaseObjectPoolConfig 中),因为在我看来它们不太适合生产环境。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-13
    • 1970-01-01
    • 1970-01-01
    • 2012-07-03
    • 2014-06-21
    • 2022-01-25
    • 2020-03-15
    相关资源
    最近更新 更多