Веб-версияОткрыть в Telegram

ПостПочему PostgreSQL откатывает изменения разных строк

20 сентября 2026
К
Катя Кондратьева
Фотография
нажмите — покажем
Фотография
нажмите — покажем
Фотография
нажмите — покажем
Почему PostgreSQL откатывает изменения разных строк Вспомнила вопрос с недавнего собеса и решила разобрать в канале. Две транзакции меняют разные счётчики, но одна из них всё равно может завершиться ошибкой. Причина в том, как база отслеживает захват объектов. Пример: таблица counters(id PRIMARY KEY, value), без триггеров и связей с другими таблицами. Обе транзакции работают в SERIALIZABLE. Сначала выполняются оба SELECT, затем оба UPDATE и попытки COMMIT: -- Транзакция T1 SELECT value FROM counters WHERE id = 1; UPDATE counters SET value = value + 1 WHERE id = 1; -- Транзакция T2 SELECT value FROM counters WHERE id = 2; UPDATE counters SET value = value + 1 WHERE id = 2; SERIALIZABLE обещает результат успешных транзакций как будто транзакции выполняются последовательно. Для проверки база запоминает, кто какую область читал. Эти отметки - SIReadLock - не блокируют запись. Они помогают заметить, что чужое изменение затронуло прочитанные данные. Пример: T1 прочитала старое значение, а T2 его изменила. Значит, в последовательном выполнении T1 должна быть раньше T2. Иначе она увидела бы новое значение. Так появляется зависимость T1 → T2. При Seq Scan - последовательном чтении таблицы - отметка чтения ставится на всю таблицу, хотя запрос меняет одну строку. Поэтому база учитывает две зависимости: - T1 меняет строку 1 → задевает отметку T2 → T2 должна быть раньше T1. - T2 меняет строку 2 → задевает отметку T1 → T1 должна быть раньше T2. Требования противоречат друг другу. PostgreSQL отклоняет одну транзакцию с ошибкой serialization_failure, код 40001. Это ложный конфликт: счётчики можно изменить в любом порядке, но широкая отметка связала две независимые операции. Чтение через индекс может сузить отметку до строки/страницы и тем самым уменьшить число конфликтов. Поэтому при разборе таких откатов полезно проверить план выполнения запроса. Но полностью исключить конфликты нельзя: приложение должно уметь при ошибке 40001 повторить всю транзакцию, включая чтения. классная статья про блокировки в постгрес #production_case
63 · 2.3K ·

Рядом в ленте

ККатя КондратьеваAI написал код. Примешь такой PR? На стриме в пятницу в 19:30 буду разрабатывать функциональность для Polymorpher с помощью Codex. Пройдём весь путь: от постаноККатя КондратьеваДрузья! Стрим переносится на среду 🙏🏻 На следующей неделе должен быть готов крупный видос. Стараюсь поставить на рельсы регулярную публикацию контента - пока в
это сообщение
ККатя КондратьеваЗнаю, что выглядит сложно, но я объясню вам, братья и сестры, зачем это нужно Конечно же, чтобы продавать такие продакшен-кейсы как собственные интересные задачККатя КондратьеваВидеосообщение
ККатя КондратьеваКатя Кондратьева@javaGymRat · канал · Технологии
2 992подписчиков1 951средний охват поста
Лента площадки Открыть в Telegram

Открытая публичная лента из поискового индекса ChatCrawler — «Google по публичному Telegram»; обновляется по мере обхода площадки. Время — UTC.

Только публичный контент, официальный API Telegram. О проекте · Вопросы · Чего мы не делаем · Убрать страницу из выдачи · Каталог · Поиск · Как мы считаем