2.1 Read uncommitted

Под «уровнем изоляции транзакций» понимается степень защиты от несогласованности данных, возникающей при параллельном выполнении транзакций. Эта защита обеспечивается внутренними механизмами СУБД без дополнительного программирования. Стандарт SQL-92 определяет шкалу из четырёх уровней изоляции.

  • Read uncommitted
  • Read committed
  • Repeatable read
  • Serializable

Обычным способом реализовать этот уровень изоляции - заблокировать данные во время выполнения изменения. Это значит, что одновременное изменение одних и тех же данных будет выполнено последовательно, и ни одно из изменений не потеряется. Также транзакции, которые делают только чтение, никогда не будут заблокированы на этом уровне изоляции.

2.2 Read committed

Большинство промышленных СУБД, включая Microsoft SQL Server, PostgreSQL и Oracle, используют завершённое чтение по умолчанию. Это защищает от неправильного чтения, но другие транзакции могут успешно завершиться и зафиксировать изменения. Поэтому первая транзакция будет работать с разным набором данных.

Завершённое чтение может быть реализовано с помощью блокировки или версионности.

Блокирование читаемых и изменяемых данных.

Записывающая транзакция блокирует данные, которые могут быть изменены транзакциями, которые читают данные при уровне изоляции read committed или выше. Это позволяет предотвратить ситуацию, когда данные могут быть прочитаны в неправильном или неполном виде, что называется «грязным чтением». Таким образом, записывающая транзакция может быть уверена, что данные, прочитанные другими транзакциями, действительно были согласованы с данными в блокированной записи. Кроме того, данные, блокируемые читающей транзакцией, будут автоматически освобождены сразу после завершения операции SELECT. Однако это может привести к ситуации, когда данные не будут одинаковыми для двух транзакций на данном уровне изоляции. Тем не менее это позволяет предотвратить появление ошибок из-за несогласованности данных в базе.

Сохранение нескольких версий параллельно изменяемых строк.

При каждом изменении строки СУБД создает новую версию этой строки. Изменившая данные транзакция продолжает работать с новой версией, а любые другие «читающие» транзакции получают последнюю зафиксированную версию. Этот подход предоставляет большую скорость, так как избегает блокировок. Однако он требует большего расхода оперативной памяти для хранения версий строк. Когда несколько транзакций одновременно пытаются изменить данные, может возникнуть ситуация, когда изменения не согласованы. Тогда транзакция, которая будет зафиксирована первой, сохранит свои изменения. Остальные не могут быть зафиксированы. СУБД откатит их и пришлет сообщение об ошибке «Запись уже изменена».

Разработчики СУБД выбирают способ реализации и могут настроить параметры. Например, MS SQL использует блокировки по умолчанию, но в версии 2005 и выше можно установить параметр READ_COMMITTED_SNAPSHOT. Oracle работает по версионной схеме. В Informix можно предотвратить конфликты читающих и пишущих транзакций с помощью параметра USELASTCOMMITTED в версии 11.1, чтобы читающая транзакция получала последние подтвержденные данные.

2.3 Repeatable read

Уровень «невидимости» – это уровень, при котором читающая транзакция «не видит» изменения данных, которые были ею ранее прочитаны. В таком случае, никакая другая транзакция не может нанести вред данным, которые в данный момент прочитаны текущей транзакцией, пока та не окончит свое выполнение. Таким образом, данные будут надежно защищены от любых несанкционированных изменений и разрушений.

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

Блокировки держатся до завершения транзакции, а не после каждого шага. Это значит, что параллелизм меньше, чем при уровне изоляции READ COMMITTED. Лучше не использовать данный и более высокие уровни транзакций без надобности.

2.4 Serializable

Самый высокий уровень изоляции. Транзакции полностью изолированы друг от друга. Каждая выполняется так, будто параллельных транзакций нет. Только на этом уровне параллельные транзакции не подвергаются эффекту «фантомного чтения».

2.5 Поддержка изоляции транзакций в реальных СУБД

СУБД не всегда поддерживают все четыре уровня и могут иметь дополнительные функции. Некоторые могут иметь различные обеспечения изоляции.

Oracle по сути не поддерживает нулевой уровень транзакционной изоляции, так как его реализация исключает «грязные чтения». Формально не поддерживается уровень Repeatable read. Поддерживаются только Read committed (по умолчанию) и Serializable.

Oracle гарантирует повторяемость чтения для отдельных команд. Например, если первая транзакция выбирает из базы набор строк, а параллельная вторая транзакция изменяет какие-то из этих строк, то результирующий набор, полученный первой транзакцией, будет содержать неизменённые строки. Кроме того, Oracle поддерживает READ-ONLY транзакции, соответствующие Serializable, но не имеющие возможности изменять данные.

Microsoft SQL Server поддерживает четыре уровня изоляции транзакций. За ними идет еще один уровень - SNAPSHOT. Он позволяет транзакции видеть состояние данных до ее запуска. Отличие от Serializable заключается в том, что транзакция может вызвать ошибку, если другая транзакция сделала изменения в тех же данных раньше. При этом выполнить COMMIT не получится.