JDBC 経由で pgbouncer にバッチ クエリを実行すると、次のエラーが発生します。
org.postgresql.util.PSQLException: ERROR: prepared statement "S_1" already exists
Web でバグ レポートを見つけましたが、それらはすべて Postgres 8.3 以下を扱っているようですが、私たちは Postgres 9 を使用しています。
エラーをトリガーするコードは次のとおりです。
this.getJdbcTemplate().update("delete from xx where username = ?", username);
this.getJdbcTemplate().batchUpdate( "INSERT INTO xx(a, b, c, d, e) " +
"VALUES (?, ?, ?, ?, ?)", new BatchPreparedStatementSetter() {
@Override
public void setValues(PreparedStatement ps, int i) throws SQLException {
ps.setString(1, value1);
ps.setString(2, value2);
ps.setString(3, value3);
ps.setString(4, value4);
ps.setBoolean(5, value5);
}
@Override
public int getBatchSize() {
return something();
}
});
これを前に見た人はいますか?
編集1:
これは、セッション プーリング以外のものを使用しているときに発生する pgBouncer の問題であることが判明しました。明らかに準備されたステートメントをサポートできないトランザクションプーリングを使用していました。セッション プーリングに切り替えることで、この問題を回避しました。
残念ながら、これは私たちのユースケースには適した修正ではありません。pgBouncer には 2 つの用途があります。システムの 1 つの部分は、プリペアド ステートメントとして最も効率的な一括更新を行い、別の部分は非常に迅速に連続して多数の接続を必要とします。pgBouncer では、セッション プーリングとトランザクション プーリングを切り替えることができないため、ニーズをサポートするためだけに、異なるポートで 2 つの個別のインスタンスを実行する必要があります。
編集2:
私はこのリンクに出くわしました , ポスターは彼自身のパッチを転がしました. 現在、安全で効果的であることが証明された場合、私たち自身の使用のためにそれを実装することを検討しています.