Postgres - ОШИБКА: подготовленный оператор «S_1» уже существует

При выполнении пакетных запросов через JDBC к pgbouncer я получаю следующее error:

org.postgresql.util.PSQLException: ERROR: prepared statement "S_1" already exists

Я нашел отчеты об ошибках в Интернете, но все они, похоже, имеют дело с 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: одна часть нашей системы выполняет массовые обновления, которые наиболее эффективны как подготовленные операторы, а другая часть требует множества соединений в очень быстрой последовательности. Поскольку pgBouncer не позволяет переключаться между пулом сеансов и пулом транзакций , мы вынуждены запускать два отдельных экземпляра на разных портах только для поддержки наших нужд.

Edit 2:

Я наткнулся на эту ссылку , где автор накатил собственный патч. В настоящее время мы ищем возможность реализовать его для собственных нужд, если он окажется безопасным и эффективным.

17
задан Erwin Brandstetter 6 October 2011 в 21:31
поделиться