Логотип YeaHub

База вопросов

Собеседования

Тренажёр

База ресурсов

Обучение

Навыки

Войти

Выбери, каким будет IT завтра — вместе c нами!

YeaHub — это полностью открытый проект, призванный объединить и улучшить IT-сферу. Наш исходный код доступен для просмотра на GitHub. Дизайн проекта также открыт для ознакомления в Figma.

© 2026 YeaHub

AI info

Карта сайта

Документы

Медиа

Назад
Вопрос про Postgres: transaction, concurrency, isolation, locking, database

Что произойдет при одновременном обновлении одной записи в двух транзакциях?

Вопрос проверяет понимание изоляции транзакций в СУБД и механизмов разрешения конфликтов при конкурентном доступе к данным.

Короткий ответ

Исход зависит от уровня изоляции транзакций и политики блокировок СУБД. При уровне READ COMMITTED или выше, вторая транзакция будет ждать, пока первая завершится (commit или rollback). Если первая транзакция фиксирует изменения, вторая может либо перезаписать их (потерянное обновление), либо получить ошибку конфликта. При использовании оптимистичных блокировок (например, по версии) вторая транзакция завершится с ошибкой при попытке коммита.

Длинный ответ

Когда две транзакции пытаются обновить одну и ту же запись одновременно, система управления базами данных (СУБД) должна обеспечить целостность данных, предотвращая аномалии. Поведение определяется настройками изоляции транзакций и механизмом управления параллельным доступом (пессимистичные или оптимистичные блокировки).

Основные сценарии

Рассмотрим типичные случаи в реляционных базах данных, таких как PostgreSQL или MySQL с движком InnoDB:

  • Пессимистичная блокировка (например, SELECT FOR UPDATE): Первая транзакция захватывает эксклюзивную блокировку строки. Вторая транзакция, пытающаяся обновить ту же строку, будет приостановлена и будет ждать, пока первая не освободит блокировку (завершится).
  • Уровень изоляции по умолчанию (READ COMMITTED): Если первая транзакция фиксирует изменения, вторая транзакция, которая ждала, обновит уже изменённую строку, используя её новое состояние. Это может привести к "потерянному обновлению", если логика второй транзакции не учитывает изменения первой.
  • Уровень изоляции REPEATABLE READ или SERIALIZABLE: В некоторых СУБД при обнаружении конфликта параллельного обновления вторая транзакция получит ошибку (например, "Could not serialize access") и должна быть перезапущена.
  • Оптимистичная блокировка: Часто реализуется на уровне приложения с использованием поля версии (version) или временной метки. Обе транзакции читают запись, но при коммите проверяют, не изменилась ли версия. Транзакция, которая коммитится второй, получит ошибку и должна повторить операцию с новыми данными.

Пример кода (оптимистичная блокировка)

Рассмотрим упрощённый пример на псевдокоде, демонстрирующий логику:

-- Предположим, таблица products имеет поле version
BEGIN TRANSACTION;
-- Транзакция 1 и 2 выполняют одинаково:
SELECT id, price, version FROM products WHERE id = 123;
-- Допустим, обе прочитали version = 5

-- Каждая вычисляет новую цену...
-- Транзакция 1 коммитится первой:
UPDATE products SET price = 100, version = 6 
WHERE id = 123 AND version = 5; -- Условие по версии
COMMIT; -- Успешно, обновилась 1 строка

-- Теперь Транзакция 2 пытается коммит:
UPDATE products SET price = 110, version = 6 
WHERE id = 123 AND version = 5; -- Но version теперь уже 6!
-- Строка не найдена для обновления, affected rows = 0
-- Приложение обнаруживает это и откатывает/повторяет транзакцию.
ROLLBACK;

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

Вывод: Конкурентное обновление одной записи — классическая проблема параллелизма. Для её решения необходимо правильно выбирать уровень изоляции транзакций и стратегию блокировок (пессимистичную для высококонфликтных сценариев или оптимистичную для чтения с редкими обновлениями), чтобы обеспечить целостность данных без чрезмерного снижения производительности.

  • Аватар

    Python Guru

    Sergey Filichkin

    Guru – это эксперты YeaHub, которые помогают развивать комьюнити.

Уровень

  • Рейтинг:

    4

  • Сложность:

    6

Навыки

  • Postgres

    Postgres

  • SQL

Ключевые слова

#transaction

#concurrency

#isolation

#locking

#database

Подпишись на Python Developer в телеграм

  • Аватар

    Python Guru

    Sergey Filichkin

    Guru – это эксперты YeaHub, которые помогают развивать комьюнити.