Логотип YeaHub

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

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

Тренажёр

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

Обучение

Навыки

Войти

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

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

© 2026 YeaHub

AI info

Карта сайта

Документы

Медиа

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

Что произойдет, если одна транзакция удерживает блокировку, а другая пытается обновить те же данные?

Этот вопрос проверяет понимание блокировок в СУБД и их влияние на параллельное выполнение транзакций, что необходимо для проектирования конкурентных и корректных приложений.

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

Вторая транзакция будет заблокирована и перейдёт в состояние ожидания. Она будет ждать, пока первая транзакция не завершится (COMMIT или ROLLBACK) и не освободит блокировку. Время ожидания может быть ограничено настройками СУБД. Если ожидание слишком долгое, может произойти таймаут или, в худшем случае, возникнуть взаимная блокировка (deadlock), если транзакции ждут ресурсы друг друга.

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

В реляционных базах данных блокировки — это механизм, обеспечивающий целостность данных при одновременном доступе. Когда транзакция изменяет строку (например, с помощью UPDATE), она обычно устанавливает на неё эксклюзивную блокировку. Это предотвращает "грязное" чтение и потерю обновлений.

Что происходит при конфликте?

Если вторая транзакция пытается обновить те же данные, её запрос не выполнится мгновенно. Вместо этого СУБД приостановит её выполнение. Транзакция переходит в состояние ожидания, пока не освободится требуемая блокировка. Поведение может зависеть от уровня изоляции транзакции.

Пример сценария и кода

Рассмотрим пример на SQL. Предположим, у нас есть таблица accounts.

-- Сессия 1 (Транзакция A)
BEGIN TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
-- Блокировка на строке с id=1 установлена.

-- Сессия 2 (Транзакция B, выполняется параллельно)
BEGIN TRANSACTION;
UPDATE accounts SET balance = balance + 50 WHERE id = 1;
-- Этот запрос будет ЖДАТЬ, пока Транзакция A не завершится.

Транзакция B "зависнет" до тех пор, пока в Сессии 1 не будет выполнено COMMIT или ROLLBACK.

Разрешение ситуации и потенциальные проблемы

  • Успешное завершение: Если Транзакция A делает COMMIT, её блокировки снимаются. Тогда Транзакция B получает блокировку, выполняет своё обновление на основе нового состояния данных и может завершиться.
  • Таймаут: Многие СУБД имеют настройку lock_timeout. Если ожидание превышает этот лимит, запрос Транзакции B будет отменён с ошибкой.
  • Взаимная блокировка (Deadlock): Более сложный сценарий. Представьте, что Транзакция A заблокировала строку 1 и ждёт строку 2, а Транзакция B заблокировала строку 2 и ждёт строку 1. Ни одна не может продолжить. В этом случае СУБД обнаружит deadlock и принудительно прервёт одну из транзакций (обычно с ошибкой), чтобы позволить другой завершиться.

Вывод: Блокировки необходимы для согласованности, но их неграмотное использование ведёт к снижению производительности и взаимным блокировкам. При проектировании приложения важно минимизировать время удержания транзакций, использовать подходящий уровень изоляции и реализовывать логику повторных попыток для обработки таймаутов и deadlock-ошибок.

  • Аватар

    Python Guru

    Sergey Filichkin

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

Уровень

  • Рейтинг:

    4

  • Сложность:

    5

Навыки

  • Postgres

    Postgres

  • SQL

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

#database

#transaction

#lock

#concurrency

#deadlock

#isolation

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

  • Аватар

    Python Guru

    Sergey Filichkin

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