Логотип YeaHub

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

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

Тренажёр

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

Обучение

Навыки

Задачи

Войти

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

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

© 2026 YeaHub

AI info

Карта сайта

Документы

Медиа

Назад
Вопрос про Postgres: deadlock, postgresql, transaction

Как СУБД (например, PostgreSQL) обрабатывает взаимоблокировки?

Этот вопрос проверяет знание конкретных механизмов обработки взаимоблокировок в современных системах управления базами данных.

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

PostgreSQL автоматически обнаруживает взаимоблокировки с помощью графа ожидания блокировок. Когда обнаруживается цикл в этом графе (что указывает на deadlock), СУБД выбирает одну транзакцию в качестве "жертвы" и откатывает ее, освобождая заблокированные ресурсы. Выбранная транзакция получает ошибку, а остальные могут продолжить выполнение. Критерий выбора "жертвы" обычно основан на стоимости отката — отменяется транзакция с наименьшей стоимостью отката.

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

PostgreSQL использует сложный механизм для обнаружения и разрешения взаимоблокировок.

1. Механизм обнаружения

  • Граф блокировок: СУБД строит ориентированный граф, где узлы — транзакции, а ребра — зависимости ожидания

  • Поиск циклов: Регулярно проверяет граф на наличие циклов

  • Проактивное обнаружение: Проверка выполняется при каждой попытке получения блокировки

2. Процесс разрешения deadlock

  • Выбор жертвы: Транзакция с наименьшей стоимостью отката

  • Откат транзакции: Полная отмена изменений "жертвы"

  • Освобождение блокировок: Все блокировки "жертвы" освобождаются

  • Уведомление: Клиент получает ошибку SQLSTATE 40P01 (deadlock_detected)

3. Пример обработки в приложении

import psycopg2
from psycopg2 import errors

def transfer_funds(conn, from_acc, to_acc, amount):
    max_retries = 3
    for attempt in range(max_retries):
        try:
            with conn.cursor() as cur:
                cur.execute("UPDATE accounts SET balance = balance - %s WHERE id = %s", 
                           (amount, from_acc))
                cur.execute("UPDATE accounts SET balance = balance + %s WHERE id = %s", 
                           (amount, to_acc))
                conn.commit()
                return True
                
        except errors.DeadlockDetected:
            conn.rollback()
            if attempt == max_retries - 1:
                raise
            print(f"Deadlock detected, retrying... ({attempt + 1}/{max_retries})")
    
    return False

4. Настройки PostgreSQL для управления deadlock

-- Время ожидания блокировки (мс)
SET lock_timeout = 5000;

-- Частота проверки deadlock (мс)
-- deadlock_timeout = 1000 (по умолчанию)

Вывод: PostgreSQL эффективно обрабатывает взаимоблокировки через автоматическое обнаружение и разрешение. Разработчики должны быть готовы обрабатывать ошибки deadlock в приложении через механизмы повтора и использовать стратегии для минимизации их возникновения.

  • Аватар

    Python Guru

    Sergey Filichkin

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

Уровень

  • Рейтинг:

    4

  • Сложность:

    7

Навыки

  • Postgres

    Postgres

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

#deadlock

#postgresql

#transaction

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

  • Аватар

    Python Guru

    Sergey Filichkin

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