В прошлом уроке транзакции то ждали друг друга, то откатывались с ошибкой. Этот урок заглядывает под капот. Сначала разберём, что значит «правильное» одновременное выполнение, потом блокировки, которые его обеспечивают, и взаимное ожидание, в которое они могут завести. В конце посмотрим, как база выполняет обещание долговечности: журнал и восстановление после сбоя.
Правильный порядок
Две транзакции идут одновременно, их команды перемешаны. Как понять, что результат правильный? Ориентир такой: результат должен совпасть с одним из вариантов, где транзакции шли бы по одной, сначала T1 целиком, потом T2, или наоборот.
Это свойство называют сериализуемостью. Потерянное обновление из прошлого урока ей не соответствует: при любом последовательном порядке у Пети списалось бы 8000, а не 3000. Уровень Serializable обещает ровно это свойство.
Блокировки
Аналогия: библиотечная книга. Читать её в читальном зале могут несколько человек одновременно. Но если кто-то взял книгу, чтобы вписывать исправления, остальным придётся подождать, пока он не вернёт её.
Блокировка устроена так же. Их два основных вида:
- разделяемая (S), для чтения: несколько транзакций держат её на одной строке одновременно;
- исключительная (X), для записи: пока её держит одна транзакция, остальные ждут.
| держат S | держат X | |
|---|---|---|
| просят S | можно | ждать |
| просят X | ждать | ждать |
Когда транзакция хочет изменить строку, которую уже меняет другая, она становится в очередь и ждёт. Вот почему в прошлом уроке второй UPDATE баланса подождал первый.
Двухфазная блокировка
Одних блокировок мало: важно, когда их снимать. Если отпустить строку слишком рано, другая транзакция успеет вклиниться, и сериализуемость пропадёт.
Правило, которое её гарантирует, называют двухфазной блокировкой, 2PL:
- Фаза роста. Транзакция только захватывает блокировки, ничего не отпуская.
- Фаза сжатия. После первой отпущенной блокировки новые захватывать нельзя.
На практике используют строгий вариант: исключительные блокировки держатся до самого COMMIT или ROLLBACK. Так другие транзакции никогда не видят и не перезаписывают незафиксированные изменения.
дальше после входа
Урок целиком открыт всем, кто вошёл. Войди по своему email, чтобы читать дальше.
Вход пока по приглашению. Если хочешь учиться, напиши Vassiliy.