Перейти к содержанию

Transactions in Depth: Уровни изоляции и блокировки

Начало урока

Транзакции углублённо: уровни изоляции и блокировки

Что на самом деле происходит, когда две транзакции одновременно трогают одни и те же строки

Главная идея: Вы уже умеете оборачивать команды в START TRANSACTION ... COMMIT. Самое сложное в продакшене - это конкурентность: множество транзакций выполняется одновременно. Уровень изоляции - это регулятор, который решает, насколько одной транзакции разрешено видеть незакоммиченную или ещё выполняющуюся работу другой, а СУБД обеспечивает это блокировками и версиями строк. Выбирайте уровень и стратегию блокировки осознанно, иначе в бою вас ждут грязные данные, потерянные обновления и взаимоблокировки.
К концу урока вы сможете:
  • назвать три феномена чтения: грязное чтение, неповторяющееся чтение, фантомное чтение;
  • выбирать между READ COMMITTED, REPEATABLE READ и SERIALIZABLE и знать значение по умолчанию в MySQL;
  • объяснить разделяемые и монопольные блокировки строк и чем SELECT ... FOR UPDATE отличается от обычного чтения;
  • распознать взаимоблокировку и применить стандартные приёмы, чтобы её избежать;
  • рассуждать об оптимистичном и пессимистичном подходах к конкурентности и выбирать один.

0. Наша рабочая схема

Каждый пример ниже работает с двумя небольшими таблицами InnoDB: банковские accounts, между которыми мы будем переводить деньги, и магазинные products, у которых мы уменьшаем stock. Столбец version нужен для раздела про оптимистичную блокировку.

CREATE TABLE accounts (
  account_id INT PRIMARY KEY,
  owner      VARCHAR(50) NOT NULL,
  balance    DECIMAL(10,2) NOT NULL
) ENGINE=InnoDB;

INSERT INTO accounts VALUES
  (1, 'Alice', 500.00),
  (2, 'Bob',   300.00),
  (3, 'Carol',   0.00);

CREATE TABLE products (
  product_id INT PRIMARY KEY,
  name       VARCHAR(50) NOT NULL,
  price      DECIMAL(8,2) NOT NULL,
  stock      INT NOT NULL,
  version    INT NOT NULL DEFAULT 0
) ENGINE=InnoDB;

INSERT INTO products (product_id, name, price, stock) VALUES
  (1, 'Keyboard', 45.00, 10),
  (2, 'Mouse',    25.00,  0),
  (3, 'Monitor', 220.00,  4);
account_idownerbalance
1Alice500.00
2Bob300.00
3Carol0.00
product_idnamepricestockversion
1Keyboard45.00100
2Mouse25.0000
3Monitor220.0040

Почему InnoDB? Уровни изоляции и построчная блокировка - это возможности движка хранения. InnoDB (движок MySQL по умолчанию) поддерживает транзакции, построчные блокировки и MVCC; старый движок MyISAM - нет, поэтому к нему всё это неприменимо.

Продолжите этот урок на YourAIZone

В полном уроке — объяснение целиком, разобранные примеры, частые ошибки, тесты с мгновенной проверкой и ИИ-репетитор. Начните сразу как гость или создайте аккаунт, чтобы сохранять прогресс.

В полном уроке

  • Объяснение целиком
  • Разобранные примеры
  • Частые ошибки и как их избежать
  • Тестовые вопросы: 15
  • ИИ-репетитор, который отвечает на вопросы по теме
  • Отслеживание прогресса для ученика, родителей и учителя