13.5. Обработка ошибок сериализации#

13.5. Обработка ошибок сериализации

13.5. Обработка ошибок сериализации

Оба уровня изоляции Repeatable Read и Serializable могут вызывать ошибки, предназначенные для предотвращения аномалий сериализации. Как уже упоминалось ранее, приложения, использующие эти уровни, должны быть готовы повторить транзакции, которые не удалось выполнить из-за ошибок сериализации. Текст сообщения об ошибке будет различаться в зависимости от конкретных обстоятельств, но он всегда будет иметь код 40001 (serialization_failure).

Следует также рекомендовать повторить попытку в случае возникновения блокировки. Это соответствует коду SQLSTATE 40P01 (deadlock_detected).

В некоторых случаях также целесообразно повторить попытку после сбоя уникального ключа, который имеет код SQLSTATE 23505 (unique_violation), и после сбоя ограничения исключения, который имеет код SQLSTATE 23P01 (exclusion_violation). Например, если приложение выбирает новое значение для столбца первичного ключа после проверки текущих сохраненных ключей, оно может получить сбой уникального ключа, потому что другой экземпляр приложения выбрал то же самое новое значение параллельно. Это фактически сбой сериализации, но сервер не обнаружит его, потому что он не может увидеть связь между вставленным значением и предыдущими чтениями. Также есть некоторые крайние случаи, когда сервер выдает ошибку уникального ключа или ограничения исключения, хотя в принципе у него достаточно информации, чтобы определить, что проблема с сериализацией является основной причиной. Хотя рекомендуется безусловно повторять ошибки serialization_failure, требуется больше внимания при повторной попытке этих других кодов ошибок, поскольку они могут представлять постоянные ошибочные условия, а не временные сбои.

Важно повторить полную транзакцию, включая всю логику, которая определяет, какой SQL запрос выполнять и/или какие значения использовать. Поэтому Tantor SE не предлагает автоматического механизма повтора, так как это не может быть сделано с гарантией корректности.

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