Перейти к основному содержимому

Изолированность транзакций в БД: MVCC, блокировки

Изолированность транзакций в БД гарантирует, что параллельные транзакции не влияют друг на друга. Предотвращает видимость промежуточных результатов транзакции для других до её завершения, сохраняя целостность данных. Это одно из свойств ACID.

Как обеспечить изолированность

  • MVCC (multiversion concurrency control) — создание отдельной версии данных для каждой транзакции.
  • Блокировка — ограничение доступа к данным.

MVCC

Принцип работы

Во время транзакции создается копия данных, в которой происходят изменения:

  1. Если транзакция завершилась успешно, копия становится основным источником, старая версия удаляется.
  2. Если во время транзакции произошла ошибка, старая версия остается основной, а копия удаляется.

Пример

Два пользователя одновременно меняют карточку товара:

  • Они открывают карточку товара, создается две копии записи о товаре.
  • Одновременно меняют поля товара. Обе копии могут стать основной записью.
  • Перед сохранением БД пытается слить две записи в одну.
    • Если конфликтов нет (менялись разные поля), транзакции завершаются успешно.
    • Если появились конфликты, обе транзакции откатываются.

Блокировки

Примеры видов блокировок

  • Централизованная
  • Распределенная
  • Независимая

Централизованная

Приложение-координатор дает доступ к БД или отклоняет запрос, если БД занята.

Алгоритмы выбора координатора

  • Забияка:
    • Рассылается сообщение о выборе координатора.
    • Отвечают все неупавшие приложения.
    • Инициатор выбирает приложение с наибольшим ID.
  • Выбор в кольце:
    • Процессы образуют кольцо, передавая сообщение о выборе координатора, пропуская неотвечающие узлы.
    • По завершению инициатору приходит список "живых" приложений.
    • Инициатор выбирает приложение с наибольшим ID.

Проблемы: координатор становится бутылочным горлышком системы, может ограничивать производительность.

Распределенная

Каждый процесс отправляет запросы на доступ к ресурсу всем другим (и себе).

Действия получателя

  • ОК: если другое приложение не имеет доступа и не запрашивает его.
  • В очередь: если получатель уже использует ресурс.
  • Сравнение времени: если получатель планирует использовать ресурс, он сравнивает время запроса со времени своего запроса.
    • ОК: если у входящего сообщения время меньше.
    • В очередь: если время больше.

После отправки запросов приложение останавливается, ждет подтверждения от остальных. Далее отправляет ОК всем в своей очереди и чистит ее.

Проблемы: при сбое одного из процессов могут возникнуть задержки, блокирующие доступ к ресурсу.

Независимая

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

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

Проблемы: частые откаты при высокой конкуренции, сложность управления копиями данных.

Пример блокировки в БД

Две транзакции (T1 и T2) работают с таблицей accounts (информация о балансах пользователей):

  1. T1: Начинает транзакцию, читает баланс аккаунта.
  2. T1: Запрашивает блокировку на аккаунт для обновления баланса.
  3. T2: Начинает транзакцию и пытается прочитать баланс аккаунта.
    • Блокировка: т.к. T1 удерживает блокировку, T2 ждет, пока T1 завершит свою транзакцию.
  4. T1: обновляет баланс и фиксирует транзакцию, освобождая блокировку.
  5. T2: читает обновленный баланс.

Что выбрать для обеспечения изолированности?

  • MVCC:
    • Если важен параллельный доступ.
    • Скорость обработки транзакции.
    • Когда важно, чтобы чтения не блокировали записи.
  • Блокировки:
    • Если нельзя допустить любую рассогласованность данных.
    • Важна строгая последовательность данных.
    • Недостаточно памяти для хранения копий.

Подборка материалов на тему блокировок и MVCC

  1. Транзакции | Подготовка к собеседованию
  2. Разбираемся с MVCC на простых примерах
  3. MVCC как один из способов обеспечения изоляции транзакций
  4. Блокировка как один из способов обеспечения изоляции транзакций
  5. Уровни изолированности транзакций для самых маленьких
  6. Уровни изоляции транзакций с примерами на PostgreSQL
  7. Распределенные блокировки с применением Redis
  8. Пишем сервис распределенных блокировок
  9. Любопытный случай взаимной блокировки транзакций в БД при использовании TransactionScope
  10. Как использовать блокировку в распределенном кэше для обеспечения согласованности данных
  11. Механизм Proof of Work и Proof of Stake в блокчейн для чайников
  12. Как работают управляемые блокировки в 1С
  13. Мьютекс (механизм синхронизации) в блокировках
  14. Распределённое управление конкурентностью
  15. Алгоритмы блокировок в распределенной среде
  16. Управление конкурентным доступом
  17. Блокировки MySQL: виды, проблемы и способы обнаружения

Видео

  1. Транзакции, MVCC, ACID в PostgreSQL
  2. Как и зачем MVCC мешает нам пользоваться базой данных и почему это не плохо
  3. MVCC в картинках и когда длинные транзакции - это проблема
  4. Как работает MVCC в In-Memory-СУБД
  5. System Design - Распределенные блокировки
  6. Java. Многопоточность. Как устроить Deadlock
  7. Что такое Mutex, Event, Semaphore
  8. Взаимное исключение, мьютексы и спинлоки
  9. Многопоточность. Recursive mutex. Shared mutex. Condition variable. Thread lock
  10. Как устроить Deadlock, а затем уйти от взаимной блокировки навсегда
  11. Блокировки | SQL для начинающих

Книги

  1. Distributed systems, Tanenbaum Читать
  2. Введение в базы данных, Дж. Дейт Читать (Часть 4 "Управление транзакциями")
  3. Технологии проектирования баз данных, Дмитрий Осипов Читать (Глава 16 "Управление транзакциями")