Четыре уровня изоляции
От Read Uncommitted до Serializable и возможности каждого уровня
«Четыре уровня изоляции» — бесплатный урок SQL Interview Prep на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения SQL Interview Prep, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс SQL Interview Prep содержит 4 уроков всего.
Вопрос, стоящий за вопросом
Когда интервьюер просит «назвать четыре уровня изоляции», настоящая проверка заключается в том, сможете ли Вы объяснить компромисс: более строгая изоляция означает меньше аномалий, но снижает параллелизм.
Стандарт SQL определяет четыре уровня, расположенные от самого слабого к самому строгому:
- READ UNCOMMITTED
- READ COMMITTED
- REPEATABLE READ
- SERIALIZABLE
Каждый уровень разрешает или запрещает определённый набор аномалий чтения. Этот урок посвящён уровням, а следующий подробно рассматривает аномалии.
Настройка уровня изоляции
Уровень изоляции задаётся для каждой транзакции или сеанса. Синтаксис почти одинаков в разных СУБД.
Если Вы не зададите уровень, у каждой базы данных будет значение по умолчанию. Знание значений по умолчанию — частый вопрос на собеседованиях, поэтому мы рассмотрим их в конце.
-- Per transaction (standard SQL)
BEGIN TRANSACTION ISOLATION LEVEL READ COMMITTED;
-- ... statements ...
COMMIT;
-- Per session
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;Уровень 1: READ UNCOMMITTED
READ UNCOMMITTED — самый слабый уровень. Транзакция может прочитать строки, изменённые другой транзакцией, но ещё не зафиксированные. Такие чтения называются грязными чтениями.
Если другая транзакция откатится, Вы прочитаете данные, которые официально никогда не существовали. Это опасно для всего, что должно быть корректным.
Примечание: PostgreSQL рассматривает READ UNCOMMITTED так же, как READ COMMITTED, поэтому фактически грязных чтений не выполняет. Сервер SQL и MySQL поддерживают этот уровень в соответствии с его назначением.
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
BEGIN;
-- may see another transaction's uncommitted (dirty) rows
SELECT balance FROM accounts WHERE id = 1;
COMMIT;Уровень 2: READ COMMITTED
READ COMMITTED гарантирует, что Вы всегда читаете только зафиксированные данные. Грязных чтений нет.
Однако каждый оператор видит последний зафиксированный снимок данных. Если Вы дважды выполните один и тот же запрос в одной транзакции, другая зафиксированная транзакция между этими выполнениями может изменить результат. Эта аномалия называется неповторяющимся чтением.
Это уровень по умолчанию в PostgreSQL, Оракле и сервере SQL, а для большинства приложений он обеспечивает разумный баланс.
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
BEGIN;
SELECT balance FROM accounts WHERE id = 1; -- returns 500
-- another transaction commits an update to id = 1
SELECT balance FROM accounts WHERE id = 1; -- may now return 700
COMMIT;Уровень 3: REPEATABLE READ
REPEATABLE READ гарантирует, что при повторном чтении строки в одной транзакции Вы оба раза получите одно и то же значение. В начале транзакции создаётся согласованный снимок данных.
Этот уровень предотвращает грязные и неповторяющиеся чтения. Стандарт всё ещё допускает фантомные чтения: новые строки, соответствующие условию WHERE и появляющиеся при повторном запросе.
Важно: это уровень по умолчанию в MySQL/InnoDB, а реализация InnoDB также блокирует большинство фантомов с помощью блокировок следующего ключа.
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
BEGIN;
SELECT balance FROM accounts WHERE id = 1; -- 500
-- another transaction commits a change to id = 1
SELECT balance FROM accounts WHERE id = 1; -- still 500 in this txn
COMMIT;Уровень 4: SERIALIZABLE
SERIALIZABLE — самый строгий уровень. База данных гарантирует, что результат параллельного выполнения транзакций будет идентичен результату их последовательного выполнения в некотором порядке.
Он предотвращает грязные, неповторяющиеся и фантомные чтения. Цена этого свойства — большее количество блокировок или, в PostgreSQL, прерывания из-за ошибок сериализации, после которых транзакции необходимо повторять.
Формулировка для собеседования: «SERIALIZABLE создаёт иллюзию, будто каждая транзакция выполнялась в одиночестве, ценой снижения параллелизма и возможных повторных попыток».
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SELECT SUM(balance) FROM accounts;
INSERT INTO audit (total) VALUES (...);
COMMIT; -- may raise a serialization_failure you retryМатрица аномалий
Самое полезное для запоминания — знать, какие аномалии допускает каждый уровень. «Да» означает, что аномалия может произойти.
- READ UNCOMMITTED: грязное=Да, неповторяющееся=Да, фантомное=Да
- READ COMMITTED: грязное=Нет, неповторяющееся=Да, фантомное=Да
- REPEATABLE READ: грязное=Нет, неповторяющееся=Нет, фантомное=Да (согласно стандарту)
- SERIALIZABLE: грязное=Нет, неповторяющееся=Нет, фантомное=Нет
Каждый следующий уровень запрещает ещё одну аномалию. В этом и заключается весь ответ.
Стандарт и реальные реализации
Важное различие для опытного специалиста: стандарт SQL определяет уровни по тому, какие аномалии они обязаны предотвращать, а не по способу их предотвращения. Реальные движки часто предотвращают больше.
- PostgreSQL
REPEATABLE READиспользует изоляцию на основе снимков и также блокирует фантомы, хотя при этом всё ещё возможна аномалия перекоса записей. - MySQL/InnoDB
REPEATABLE READблокирует фантомы с помощью блокировок следующего ключа. - PostgreSQL
SERIALIZABLEиспользует SSI (изоляцию сериализуемых снимков), прерывая транзакции при конфликте вместо применения большого количества блокировок.
Упоминание этого показывает, что Вы понимаете: стандарт задаёт нижнюю границу, а не описывает точное поведение.
Уровни по умолчанию в разных СУБД
Значения по умолчанию постоянно встречаются в вопросах. Запомните их:
- PostgreSQL: READ COMMITTED
- Оракл: READ COMMITTED (грязных чтений не бывает)
- Сервер SQL: READ COMMITTED
- MySQL (InnoDB): REPEATABLE READ
Исключение в MySQL — любимая каверза на собеседованиях. Если Вас спрашивают «каков уровень изоляции по умолчанию?», сначала обязательно уточните, о какой СУБД идёт речь.
Выбор уровня на практике
Как принять решение? Рассматривайте его как выбор между риском и пропускной способностью.
- Используйте READ COMMITTED для типичных систем OLTP: он работает быстро и предотвращает грязные чтения.
- Используйте REPEATABLE READ, когда транзакция несколько раз читает одни и те же данные и их значение должно оставаться неизменным (например, в отчётах и многоэтапных вычислениях).
- Используйте SERIALIZABLE для логики, критичной с точки зрения корректности, когда недопустима любая аномалия, и предусмотрите логику повторных попыток после прерываний.
В рабочей среде почти никогда не следует использовать READ UNCOMMITTED.
Распространённые дополнительные вопросы
После перечисления уровней интервьюеры обычно задают короткие дополнительные вопросы. Подготовьте краткие ответы:
- «Какой уровень предотвращает грязные чтения, но допускает неповторяющиеся?» READ COMMITTED.
- «Какую единственную аномалию REPEATABLE READ всё ещё допускает согласно стандарту?» Фантомные чтения.
- «Почему бы всегда не использовать SERIALIZABLE?» Он снижает параллелизм и может вынуждать повторять транзакции после ошибок сериализации.
- «Более высокий уровень требует больше ресурсов?» Да, из-за блокировок или затрат на прерывание и повторный запуск.
Мгновенные ответы на эти вопросы доказывают, что Вы усвоили иерархию уровней, а не просто заучили её.
Быстрая проверка
Это один из фактов об уровнях по умолчанию, который проверяют чаще всего.
Итоги: четыре уровня, один компромисс
Четыре уровня изоляции образуют последовательность от самого слабого к самому строгому: READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, SERIALIZABLE. Каждый следующий уровень запрещает ещё одну аномалию (грязное, неповторяющееся или фантомное чтение), снижая при этом параллелизм.
Запомните значения по умолчанию (READ COMMITTED везде, кроме MySQL, где используется REPEATABLE READ) и учитывайте, что реальные движки часто предотвращают больше аномалий, чем требует стандарт. Далее мы рассмотрим три аномалии чтения, которые эти уровни призваны предотвращать.
Часто задаваемые вопросы
Урок «Четыре уровня изоляции» бесплатный?
Да — полный текст урока «Четыре уровня изоляции» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс SQL Interview Prep, подпишись на CoddyKit PRO. Курс SQL Interview Prep содержит 4 уроков всего.
Чему я научусь в уроке «Четыре уровня изоляции»?
От Read Uncommitted до Serializable и возможности каждого уровня Ты практикуешь SQL Interview Prep с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать SQL Interview Prep?
Предыдущий опыт не требуется. SQL Interview Prep на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Четыре уровня изоляции»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке SQL Interview Prep?
Да. Каждый урок SQL Interview Prep включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Объяснение свойств ACID
- Четыре уровня изоляции
- Грязное, неповторяемое и фантомное чтение
- Взаимные блокировки, блокировки и MVCC