При использовании коннектора JDB C Postgres, есть ли случаи, когда транзакции будут частично зафиксированы, когда перед вызовом commit генерируется исключение? - PullRequest
0 голосов
/ 06 марта 2020

Я использую пакетный оператор, вставляющий несколько строк в таблицу в транзакции. Иногда триггер вставки будет RAISE исключением на стороне базы данных, и я ожидаю, что вся транзакция не будет зафиксирована. На стороне клиента я не делаю никакой специальной обработки: statement.executeBatch() выдает исключение, и я позволяю ему распространяться и выходить из программы без вызова db.commit().

Однако я заметил, что иногда некоторые строки похоже, что вставляется, хотя executeBatch выдает исключение Java, потому что другая строка вызвала исключение PG при вставке. Есть ли случаи, когда мне следовало ожидать этого?

Я звоню db.setAutoCommit(false) в начале программы.

То, что я делаю, по сути похоже на этот (синтаксис Kotlin) :

val example = db.prepareStatement("insert into example (id, not_nullable) values (?, ?)")
example.clearBatch()
(1..1000).forEach {
    example.setInt(1, it)
    example.setString(2, if (it == 13) null else it.toString())
    example.addBatch()
}
example.executeBatch()
db.commit()

Однако я не смог воспроизвести это неожиданное поведение, выполнив этот простой пример 100 раз на моей машине (т.е. строки не вставлены, как первоначально ожидалось), поэтому мне интересно, если это так состояние гонки (возможно, связанное с выходом или очисткой соединения) или если я упускаю важную деталь, которая может вызвать это.

(я использую PostgreSQL 11.5 на Amazon RDS и org. postgresql: postgresql:. 42,2)

...