HikariCP:5 次查询后,Postgres timestamptz 列时区在 PreparedStatement 的结果集中消失
HikariCP: Postgres timestamptz column timezone disappears in resultset of PreparedStatement after 5 queries
我在 play2.4 中的光滑映射不起作用,我将问题归结为:如果我从 table 和 timestamp with time zone
做一个简单的 select列,时区会在一段时间后从结果中消失。此消息末尾的示例产生以下输出:
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 直接创建连接,它就可以工作。
- 如果我在循环中的每个查询结束时不关闭连接(即我泄漏了连接),它会起作用
- 如果我每次都使用相同的连接而不 creating/closing 一个新连接(即从池中获取一个并释放它),它就可以工作
- 如果我每次使用标准 DriverManager.getConnection 和相同的 URL 创建并关闭一个新连接,它就可以工作。
- 如果我不准备声明,它会起作用
- 如果我准备语句两次(即使不使用第二个),它也有效
- 如果我准备与第一个不同的第二个语句,它不起作用
我尝试了普通版和 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();
}
}
}
这里已经回答了这个问题:https://github.com/brettwooldridge/HikariCP/issues/473
There were some issues with dates / timezones when the JDBC driver
switches to server-side prepared statements. By default this happens
after 5 prepared statement executions (see prepareThreshold parameter
of postgresql JDBC).
所以这是 postgres jdbc 驱动程序中的错误。似乎目前唯一的解决方法是设置 prepareThreshold=0 或切换到没有时区的时间戳。
我在 play2.4 中的光滑映射不起作用,我将问题归结为:如果我从 table 和 timestamp with time zone
做一个简单的 select列,时区会在一段时间后从结果中消失。此消息末尾的示例产生以下输出:
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 直接创建连接,它就可以工作。
- 如果我在循环中的每个查询结束时不关闭连接(即我泄漏了连接),它会起作用
- 如果我每次都使用相同的连接而不 creating/closing 一个新连接(即从池中获取一个并释放它),它就可以工作
- 如果我每次使用标准 DriverManager.getConnection 和相同的 URL 创建并关闭一个新连接,它就可以工作。
- 如果我不准备声明,它会起作用
- 如果我准备语句两次(即使不使用第二个),它也有效
- 如果我准备与第一个不同的第二个语句,它不起作用
我尝试了普通版和 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();
}
}
}
这里已经回答了这个问题:https://github.com/brettwooldridge/HikariCP/issues/473
There were some issues with dates / timezones when the JDBC driver switches to server-side prepared statements. By default this happens after 5 prepared statement executions (see prepareThreshold parameter of postgresql JDBC).
所以这是 postgres jdbc 驱动程序中的错误。似乎目前唯一的解决方法是设置 prepareThreshold=0 或切换到没有时区的时间戳。