通过JDBC对pgbouncer执行批处理查询时,出现以下错误:
org.postgresql.util.PSQLException:错误:准备好的语句“S_1”已存在
我在网上找到了一些bug报告,但它们似乎都是针对Postgres 8.3或更低版本的,而我们现在使用的是Postgres 9
以下是触发错误的代码:
this.getJdbcTemplate().update(“从xx删除,其中用户名=?”,用户名);
this.getJdbcTemplate().batchUpdate(“插入到xx(a,b,c,d,e)”中+
“值(?,,,,,?,?)”,新的BatchPreparedStatementSetter(){
@凌驾
公共void setValues(PreparedStatement ps,int i)引发SQLException{
ps.setString(1,值1);
ps.setString(2,值2);
ps.setString(3,值3);
ps.setString(4,值4);
ps.setBoolean(5,价值5);
}
@凌驾
public int getBatchSize(){
归还某物();
}
});
有人见过这个吗
编辑1:
这是一个pgBouncer问题,在使用除会话池以外的任何方法时都会发生。我们使用的是事务池,它显然不能支持准备好的语句。通过切换到会话池,我们绕过了这个问题
不幸的是,对于我们的用例来说,这不是一个很好的修复方法。pgBouncer有两种不同的用途:我们系统的一部分进行批量更新,这在准备语句时是最有效的,另一部分需要快速连续的许多连接。由于pgBouncer不允许在会话池和事务池之间来回切换,我们不得不在不同的端口上运行两个单独的实例,以满足我们的需要
编辑2:
我无意中看到了这个链接,海报上有他自己的补丁。如果它被证明是安全有效的,我们目前正在考虑将其用于我们自己的用途
禁用JDBC中的准备语句。
对于JDBC来说,正确的方法是添加;prepareThreshold=0“;参数来连接字符串
jdbc:postgresql://ip:port/db_name?prepareThreshold=0