Изоляция (системы баз данных)

редактировать

В системах баз данных изоляция определяет, как целостность транзакции видна другим пользователям и системам.

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

Изоляция обычно определяется на уровне базы данных как свойство, определяющее, как и когда изменения, внесенные одной операцией, становятся видимыми для других. В старых системах это может быть реализовано системно, например, с использованием временных таблиц. В двухуровневых системах для поддержания изоляции требуется диспетчер обработки транзакций (TP). В многоуровневых системах (например, несколько веб-сайтов, пытающихся забронировать последнее место в рейсе) требуется комбинация хранимых процедур и управления транзакциями для подтверждения бронирования и отправки подтверждения клиенту.

Изоляция - одно из четырех свойств КИСЛОТЫ, наряду с атомарностью, согласованностью и долговечностью.

СОДЕРЖАНИЕ

  • 1 Контроль параллелизма
  • 2 Чтение явлений
    • 2.1 Грязные чтения
    • 2.2 Неповторяющиеся чтения
    • 2.3 Призрачное чтение
  • 3 уровня изоляции
    • 3.1 Сериализуемый
    • 3.2 Повторяющиеся чтения
    • 3.3 Прочитано совершено
    • 3.4 Чтение незафиксированных
  • 4 Уровень изоляции по умолчанию
  • 5 уровней изоляции, явления чтения и блокировки
    • 5.1 Уровни изоляции и явления чтения
  • 6 См. Также
  • 7 ссылки
  • 8 Внешние ссылки

Контроль параллелизма

Контроль параллелизма включает в себя базовые механизмы СУБД, которые обеспечивают изоляцию и гарантируют корректность. Он активно используется СУБД и механизмами хранения как для обеспечения правильного выполнения параллельных транзакций, так и (с помощью различных механизмов) правильности других процессов СУБД. Связанные с транзакциями механизмы обычно ограничивают время операций доступа к данным базы данных ( расписания транзакций ) определенными заказами, которые характеризуются свойствами графика сериализуемости и восстанавливаемости. Ограничение выполнения операции доступа к базе данных обычно означает снижение производительности (измеряемой скоростью выполнения), и, таким образом, механизмы управления параллелизмом обычно предназначены для обеспечения наилучшей производительности, возможной в условиях ограничений. Часто, когда это возможно без ущерба для правильности, свойство сериализуемости ухудшается для повышения производительности. Однако возможность восстановления не может быть нарушена, поскольку это обычно приводит к быстрому нарушению целостности базы данных.

Двухфазная блокировка - это наиболее распространенный метод управления параллелизмом транзакций в СУБД, используемый для обеспечения как сериализуемости, так и возможности восстановления для корректности. Чтобы получить доступ к объекту базы данных, транзакция сначала должна получить блокировку для этого объекта. В зависимости от типа операции доступа (например, чтение или запись объекта) и от типа блокировки получение блокировки может быть заблокировано и отложено, если другая транзакция удерживает блокировку для этого объекта.

Читать явления

Стандарт ANSI / ISO SQL 92 относится к трем различным явлениям чтения, когда транзакция 1 считывает данные, которые транзакция 2 могла изменить.

В следующих примерах имеют место две транзакции. В первом выполняется Запрос 1. Затем во второй транзакции выполняется и фиксируется запрос 2. Наконец, в первой транзакции снова выполняется запрос 1.

Запросы используют следующую таблицу данных:

пользователи
я бы название возраст
1 Джо 20
2 Джилл 25

Грязные чтения

Грязное чтение (ака незавершенной зависимости) возникает, когда транзакция разрешено считывать данные из строки, которая была изменена на другой выполняющуюся операцию и еще не совершала.

Грязное чтение работает аналогично неповторимому чтению ; однако вторую транзакцию не нужно фиксировать, чтобы первый запрос возвратил другой результат. Единственное, что можно предотвратить на уровне изоляции READ UNCOMMITTED, - это неупорядоченное отображение обновлений в результатах; то есть более ранние обновления всегда будут появляться в наборе результатов перед более поздними обновлениями.

В нашем примере транзакция 2 изменяет строку, но не фиксирует изменения. Затем транзакция 1 считывает незафиксированные данные. Теперь, если транзакция 2 откатывает свои изменения (уже прочитанные транзакцией 1) или обновляет различные изменения в базе данных, тогда представление данных может быть неправильным в записях транзакции 1.

Транзакция 1 Транзакция 2
/* Query 1 */ SELECT age FROM users WHERE id = 1; /* will read 20 */
/* Query 2 */ UPDATE users SET age = 21 WHERE id = 1; /* No commit here */
/* Query 1 */ SELECT age FROM users WHERE id = 1; /* will read 21 */
ROLLBACK; /* lock-based DIRTY READ */

Но в этом случае не существует строки с идентификатором 1 и возрастом 21.

Неповторяющиеся чтения

Неповторяющиеся чтения происходит, когда, в ходе операции, строка извлекается в два раза, а значения в пределах строки различаются между читает.

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

Транзакция 1 Транзакция 2
/* Query 1 */ SELECT * FROM users WHERE id = 1;
/* Query 2 */ UPDATE users SET age = 21 WHERE id = 1; COMMIT; /* in multiversion concurrency  control, or lock-based READ COMMITTED */
/* Query 1 */ SELECT * FROM users WHERE id = 1; COMMIT; /* lock-based REPEATABLE READ */

В этом примере транзакция 2 успешно фиксируется, что означает, что ее изменения в строке с идентификатором 1 должны стать видимыми. Однако транзакция 1 уже увидела другое значение возраста в этой строке. На уровнях изоляции SERIALIZABLE и REPEATABLE READ СУБД должна возвращать старое значение для второго SELECT. При READ COMMITTED и READ UNCOMMITTED СУБД может вернуть обновленное значение; это неповторимое чтение.

Есть две основные стратегии, используемые для предотвращения неповторяющихся чтений. Первый - отложить выполнение транзакции 2 до тех пор, пока транзакция 1 не будет зафиксирована или откат. Этот метод используется при использовании блокировки и производит последовательное расписание T1, T2. Последовательное расписание демонстрирует повторяющееся поведение чтения.

В другой стратегии, используемой в управлении параллелизмом с несколькими версиями, транзакция 2 может быть зафиксирована первой, что обеспечивает лучший параллелизм. Однако транзакция 1, которая началась до транзакции 2, должна продолжать работать с предыдущей версией базы данных - моментальным снимком момента ее запуска. Когда транзакция 1 в конечном итоге пытается выполнить фиксацию, СУБД проверяет, будет ли результат фиксации транзакции 1 эквивалентен расписанию T1, T2. Если это так, то Транзакция 1 может продолжаться. Однако, если он не может быть признан эквивалентным, транзакция 1 должна откатиться с ошибкой сериализации.

При использовании метода управления параллелизмом на основе блокировки в режиме изоляции REPEATABLE READ строка с ID = 1 будет заблокирована, таким образом блокируя запрос 2 до тех пор, пока первая транзакция не будет зафиксирована или откат. В режиме READ COMMITTED при втором выполнении запроса 1 возраст изменился бы.

При мультиверсионном управлении параллелизмом на уровне изоляции SERIALIZABLE оба запроса SELECT видят моментальный снимок базы данных, сделанный в начале транзакции 1. Следовательно, они возвращают одни и те же данные. Однако, если транзакция 2 затем попытается ОБНОВИТЬ эту строку, произойдет сбой сериализации, и транзакция 1 будет вынуждена откатиться.

На уровне изоляции READ COMMITTED каждый запрос видит моментальный снимок базы данных, сделанный в начале каждого запроса. Таким образом, каждый из них видит разные данные для обновленной строки. В этом режиме невозможен сбой сериализации (поскольку не дается никаких обещаний о сериализуемости), и транзакцию 1 не нужно будет повторять.

Призрак читает

Фантомное чтение происходит, когда, в ходе операции, новые строки будут добавлены или удалены другой транзакцией к записи считываются.

Это может произойти, если блокировки диапазона не получены при выполнении операции SELECT. .. WHERE. Фантомный читает аномалию является частным случаем неповторяющихся чтений, когда сделка 1 повторы дальней SELECT... WHERE и между обеими операциями, сделка 2 создает запрос (т.е. INSERT ) новые строки (в целевой таблице), которые выполняют, что ГДЕ пункт.

Транзакция 1 Транзакция 2
/* Query 1 */ SELECT * FROM users WHERE age BETWEEN 10 AND 30;
/* Query 2 */ INSERT INTO users(id, name, age) VALUES (3, 'Bob', 27); COMMIT;
/* Query 1 */ SELECT * FROM users WHERE age BETWEEN 10 AND 30; COMMIT;

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

В режиме изоляции SERIALIZABLE запрос 1 приведет к блокировке всех записей с возрастом в диапазоне от 10 до 30, поэтому запрос 2 будет блокироваться до тех пор, пока не будет зафиксирована первая транзакция. В режиме REPEATABLE READ диапазон не будет заблокирован, что позволит вставить запись. Следовательно, второй оператор запроса 1 не вернет тот же результат, что и первый.

Уровни изоляции

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

Большинство СУБД предлагают несколько уровней изоляции транзакций, которые контролируют степень блокировки, возникающей при выборе данных. Для многих приложений баз данных большинство транзакций базы данных может быть построено так, чтобы не требовать высоких уровней изоляции (например, уровень SERIALIZABLE), тем самым снижая накладные расходы на блокировку для системы. Программист должен тщательно проанализировать код доступа к базе данных, чтобы гарантировать, что любое ослабление изоляции не вызовет программных ошибок, которые трудно найти. И наоборот, если используются более высокие уровни изоляции, вероятность тупиковой ситуации увеличивается, что также требует тщательного анализа и методов программирования, которых следует избегать.

Поскольку каждый уровень изоляции сильнее, чем нижеприведенные, в том смысле, что ни один более высокий уровень изоляции не допускает действия, запрещенного более низким, стандарт разрешает СУБД выполнять транзакцию на более высоком уровне изоляции, чем запрошенный (например, «Чтение подтверждено» транзакция может фактически выполняться на уровне изоляции «Повторяющееся чтение»).

Уровни изоляции, определенные стандартом ANSI / ISO SQL, перечислены ниже.

Сериализуемый

Это высший уровень изоляции.

При реализации СУБД с управлением параллелизмом на основе блокировок для сериализуемости требуется снятие блокировок чтения и записи (полученных для выбранных данных) в конце транзакции. Кроме того, блокировки диапазона должны быть получены, когда запрос SELECT использует предложение WHERE с диапазоном, особенно во избежание явления фантомного чтения.

При использовании управления параллелизмом без блокировки блокировки не устанавливаются; однако, если система обнаруживает конфликт записи между несколькими параллельными транзакциями, только одна из них может быть зафиксирована. Дополнительные сведения по этой теме см. В разделе « Изоляция моментальных снимков».

Источник: (Второй черновик неофициального обзора) ISO / IEC 9075: 1992, Язык баз данных SQL - 30 июля 1992 г.: Гарантированно сериализуемое выполнение параллельных SQL-транзакций на уровне изоляции SERIALIZABLE. Сериализуемое выполнение определяется как выполнение операций по одновременному выполнению SQL-транзакций, которое дает тот же эффект, что и некоторое последовательное выполнение тех же самых SQL-транзакций. Последовательное выполнение - это такое, при котором каждая SQL-транзакция выполняется до завершения до начала следующей SQL-транзакции.

Повторяющиеся чтения

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

На этом уровне изоляции в некоторых системах возможен перекос при записи. Перекос при записи - это явление, когда две записи разрешены в один и тот же столбец (столбцы) в таблице двумя разными авторами (которые ранее читали столбцы, которые они обновляют), в результате чего столбец имеет данные, которые представляют собой смесь двух транзакций..

Прочитано совершено

На этом уровне изоляции реализация СУБД управления параллелизмом на основе блокировок сохраняет блокировки записи (полученные для выбранных данных) до конца транзакции, но блокировки чтения снимаются, как только выполняется операция SELECT (так что явление неповторяемого чтения может произойти на этом уровне изоляции). Как и на предыдущем уровне, блокировки диапазона не управляются.

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

Читать незафиксированные

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

Уровень изоляции по умолчанию

Уровень изоляции по умолчанию различных СУБД варьируется в широких пределах. Большинство баз данных, в которых есть транзакции, позволяют пользователю устанавливать любой уровень изоляции. Некоторым СУБД также требуется дополнительный синтаксис при выполнении оператора SELECT для получения блокировок (например, SELECT... FOR UPDATE для получения исключительных блокировок записи для строк, к которым осуществляется доступ).

Однако приведенные выше определения подверглись критике как неоднозначные и не совсем точно отражающие изоляцию, обеспечиваемую многими базами данных:

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

Есть и другие критические замечания относительно определения изоляции ANSI SQL, поскольку оно побуждает разработчиков делать «плохие вещи»:

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

Уровни изоляции, явления чтения и блокировки

Уровни изоляции против явлений чтения

'+' - возможно '-' - невозможно

             Читать явления Уровень изоляции Грязные чтения Потерянные обновления Неповторяющиеся чтения Фантомы
Читать незафиксированные + + + +
Прочитано совершено - + + +
Повторяющееся чтение - - - +
Сериализуемый - - - -

Аномалия Serializable - это не то же самое, что Serializable. То есть необходимо, но недостаточно, чтобы в сериализуемом расписании не было всех трех типов явлений.

Смотрите также

Рекомендации

Внешние ссылки

Последняя правка сделана 2023-03-31 01:30:29
Содержание доступно по лицензии CC BY-SA 3.0 (если не указано иное).
Обратная связь: support@alphapedia.ru
Соглашение
О проекте