【问题标题】:HikariCP: Postgres timestamptz column timezone disappears in resultset of PreparedStatement after 5 queriesHikariCP:Postgres timestamptz 列时区在 5 次查询后在 PreparedStatement 的结果集中消失
【发布时间】:2015-10-27 20:41:20
【问题描述】:

我在 play2.4 中的平滑映射不起作用,我将问题归结为:如果我从带有 timestamp with time zone 列的表中进行简单选择,则时区会在一段时间后从结果中消失。此消息末尾的示例产生以下输出: 2015-10-27 20:45:13.459+01 2015-10-27 20:45:13.459+01 2015-10-27 20:45:13.459+01 2015-10-27 20:45:13.459+01 2015-10-27 20:45:13.459+01 // from now on, the timezone is never returned (even after 1000 queries) 2015-10-27 20:45:13.459 2015-10-27 20:45:13.459 2015-10-27 20:45:13.459 2015-10-27 20:45:13.459 ...

  • 如果我不使用 HikariCP 直接创建连接,它就可以工作。
  • 如果我没有在循环中的每个查询结束时关闭连接(即泄漏连接),它会起作用
  • 如果我每次都使用相同的连接而不创建/关闭一个新连接(即从池中获取一个并释放它),它可以工作
  • 如果我每次使用具有相同 URL 的标准 DriverManager.getConnection 创建并关闭一个新连接,它就可以工作。
  • 如果我不准备声明,它会起作用
  • 如果我准备了两次声明(即使没有使用第二次),它也有效
  • 如果我准备与第一个不同的第二个语句,它将不起作用

我尝试了普通版和 java6 版的 hikaricp。 我正在使用 postgres 9.4。我在 scala 中工作,但我在 java 中创建了示例以扩大受众范围;)

我打开了一个问题,但我有点着急,所以如果有人知道该怎么做... 如果有人能指出如何在 play 2.4 中使用 bonecp 或其他任何东西,我也将不胜感激。

您可以使用仅具有 HikariCP 和 postgres 依赖项的项目重现该问题:

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class TestHikari {
    public static void main(String[] args) throws Exception {
        HikariConfig conf = new HikariConfig();
        conf.setJdbcUrl("jdbc:postgresql://localhost/postgres");
        conf.setDriverClassName("org.postgresql.Driver");

        HikariDataSource ds = new HikariDataSource(conf);
        Connection ddlconn = ds.getConnection();
        try { ddlconn.createStatement().execute("DROP TABLE TEST"); } catch(Exception ignored) {}
        ddlconn.createStatement().execute("CREATE TABLE TEST (ts TIMESTAMP with time zone)");
        ddlconn.createStatement().execute("insert into test(ts) values('2015-10-27 20:45:13.459+01')");
        ddlconn.close();

        for (int i = 0; i< 10; i++) {
            Connection conn = ds.getConnection();
            PreparedStatement stmt = conn.prepareStatement("select ts from TEST");
            //if I uncomment the next line, it works!
            //conn.prepareStatement("select ts from TEST");
            ResultSet rs = stmt.executeQuery();
            rs.next();

            System.out.println(rs.getString(1));

            conn.close();
        }
    }
}

【问题讨论】:

  • 映射是自己写的还是自己生成的?
  • 在了解了问题的实质之后,我终于找到了这个bug。 github.com/pgjdbc/pgjdbc/issues/130 - 仍未解决。我必须切换到没有 tz 的时间戳。无论如何,时间戳 tz 毫无用处

标签: java postgresql jdbc playframework-2.0 hikaricp


【解决方案1】:

此问题已在此处得到解答:https://github.com/brettwooldridge/HikariCP/issues/473

使用 JDBC 驱动程序时,日期/时区存在一些问题 切换到服务器端准备好的语句。默认情况下会发生这种情况 在 5 次准备好的语句执行后(参见 prepareThreshold 参数 postgresql JDBC)。

所以这是 postgres jdbc 驱动程序中的一个错误。目前看来唯一的解决方法是设置 prepareThreshold=0 或切换到没有时区的时间戳。

【讨论】:

  • 请不要只发布对其他 Stack Overflow 问题的链接答案。相反,投票/标记以关闭为重复,或者,如果问题不是重复的,则定制此特定问题的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-13
  • 1970-01-01
  • 2018-01-15
  • 2021-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多