Вам бонус- начислено 1 монета за дневную активность. Сейчас у вас 1 монета

Уровень изолированности транзакций, феномены(аномалии) данных

Лекция



Привет, Вы узнаете о том , что такое уровень изолированности транзакций, Разберем основные их виды и особенности использования. Еще будет много подробных примеров и описаний. Для того чтобы лучше понимать что такое уровень изолированности транзакций, транзакции, аномалии данных, феномен данных , настоятельно рекомендую прочитать все из категории Базы данных, знаний и хранилища данных. Big data, СУБД и SQL и noSQL.

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

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

Транзакции — это группа операций на чтение/запись, выполняющихся только если все операции из группы успешно выполнены.

Содержание

  • 1 Проблемы параллельного доступа с использованием транзакций
    • 1.1 Потерянное обновление
    • 1.2 «Грязное» чтение
    • 1.3 Неповторяющееся чтение
    • 1.4 Фантомное чтение
  • 2 Уровни изоляции
    • 2.1 Read uncommitted (чтение незафиксированных данных)
    • 2.2 Read committed (чтение фиксированных данных)
    • 2.3 Repeatable read (повторяемость чтения)
    • 2.4 Serializable (упорядочиваемость)
    • 2.5 Поддержка изоляции транзакций в реальных СУБД
  • 3 Поведение при различных уровнях изолированности

Уровень изолированности транзакций, феномены(аномалии) данных

Уровень изолированности транзакций, феномены(аномалии) данных

Уровень изолированности транзакций, феномены(аномалии) данных

Проблемы параллельного доступа с использованием транзакций

Уровень изолированности транзакций, феномены(аномалии) данных

При параллельном выполнении транзакций возможны следующие проблемы:

  • потерянное обновление (англ. lost update) — при одновременном изменении одного блока данных разными транзакциями одно из изменений теряется;
  • «грязное» чтение (англ. dirty read) — чтение данных, добавленных или измененных транзакцией, которая впоследствии не подтвердится (откатится);
  • неповторяющееся чтение (англ. non-repeatable read) — при повторном чтении в рамках одной транзакции ранее прочитанные данные оказываются измененными;
  • фантомное чтение (англ. phantom reads) — одна транзакция в ходе своего выполнения несколько раз выбирает множество строк по одним и тем же критериям. Другая транзакция в интервалах между этими выборками добавляет или удаляет строки или изменяет столбцы некоторых строк, используемых в критериях выборки первой транзакции, и успешно заканчивается. В результате получится, что одни и те же выборки в первой транзакции дают разные множества строк.

Рассмотрим ситуации, в которых возможно возникновение данных проблем.

Потерянное обновление

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

Предположим, имеются две транзакции, выполняемые одновременно:

Транзакция 1 Транзакция 2
UPDATE tbl1 SET f2=f2+20 WHERE f1=1; UPDATE tbl1 SET f2=f2+25 WHERE f1=1;

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

  1. Обе транзакции одновременно читают текущее состояние поля. Точная физическая одновременность здесь не обязательна, достаточно, чтобы вторая по порядку операция чтения выполнилась до того, как другая транзакция запишет свой результат.
  2. Обе транзакции вычисляют новое значение поля, прибавляя, соответственно, 20 и 25 к ранее прочитанному значению.
  3. Транзакции пытаются записать результат вычислений обратно в поле f2. Поскольку физически одновременно две записи выполнить невозможно, в реальности одна из операций записи будет выполнена раньше, другая позже. При этом вторая операция записи перезапишет результат первой.

В результате значение поля f2 по завершении обеих транзакций может увеличиться не на 45, а на 20 или 25, то есть одна из изменяющих данные транзакций «пропадет».

Уровень изолированности транзакций, феномены(аномалии) данных

«Грязное» чтение

Чтение данных, добавленных или измененных транзакцией, которая впоследствии не подтвердится (откатится).

Предположим, имеются две транзакции, открытые различными приложениями, в которых выполнены следующие SQL-операторы:

Транзакция 1 Транзакция 2
SELECT f2 FROM tbl1 WHERE f1=1;
UPDATE tbl1 SET f2=f2+1 WHERE f1=1;
SELECT f2 FROM tbl1 WHERE f1=1;
ROLLBACK WORK;

В транзакции 1 изменяется значение поля f2, а затем в транзакции 2 выбирается значение этого поля. После этого происходит откат транзакции 1. В результате значение, полученное второй транзакцией, будет отличаться от значения, хранимого в базе данных.

Уровень изолированности транзакций, феномены(аномалии) данных

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

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

Предположим, имеются две транзакции, открытые различными приложениями, в которых выполнены следующие SQL-операторы:

Транзакция 1 Транзакция 2
SELECT f2 FROM tbl1 WHERE f1=1;
UPDATE tbl1 SET f2=f2+1 WHERE f1=1;
COMMIT;
SELECT f2 FROM tbl1 WHERE f1=1;

В транзакции 2 выбирается значение поля f2, затем в транзакции 1 изменяется значение поля f2. При повторной попытке выбора значения из поля f2 в транзакции 2 будет получен другой результат. Эта ситуация особенно неприемлема, когда данные считываются с целью их частичного изменения и обратной записи в базу данных.

Уровень изолированности транзакций, феномены(аномалии) данных

Фантомное чтение

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

Предположим, имеется две транзакции, открытые различными приложениями, в которых выполнены следующие SQL-операторы:

Транзакция 1 Транзакция 2
SELECT SUM(f2) FROM tbl1;
INSERT INTO tbl1 (f1,f2) VALUES (15,20);
COMMIT;
SELECT SUM(f2) FROM tbl1;

В транзакции 2 выполняется SQL-оператор, использующий все значения поля f2. Затем в транзакции 1 выполняется вставка новой строки, приводящая к тому, что повторное выполнение SQL-оператора в транзакции 2 выдаст другой результат. Такая ситуация называется фантомным чтением. От неповторяющегося чтения оно отличается тем, что результат повторного обращения к данным изменился не из-за изменения/удаления самих этих данных, а из-за появления новых (фантомных) данных.

Уровень изолированности транзакций, феномены(аномалии) данных

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

Под «уровнем изоляции транзакций» понимается степень обеспечиваемой внутренними механизмами СУБД (то есть не требующей специального программирования) защиты от всех или некоторых видов вышеперечисленных несогласованностей данных, возникающих при параллельном выполнении транзакций. Стандарт SQL-92 определяет шкалу из четырех уровней изоляции: Read uncommitted, Read committed, Repeatable read, Serializable. Первый из них является самым слабым, последний — самым сильным, каждый последующий включает в себя все предыдущие.

Read uncommitted (чтение незафиксированных данных)

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

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

Read committed (чтение фиксированных данных)

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

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

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

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

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

При каждом изменении строки СУБД создает новую версию этой строки, с которой продолжает работать изменившая данные транзакция, в то время как любой другой «читающей» транзакции возвращается последняя зафиксированная версия. Преимущество такого подхода в том, что он обеспечивает бо́льшую скорость, так как предотвращает блокировки. Однако он требует, по сравнению с первым, существенно бо́льшего расхода оперативной памяти, которая тратится на хранение версий строк. Кроме того, при параллельном изменении данных несколькими транзакциями может создаться ситуация, когда несколько параллельных транзакций произведут несогласованные изменения одних и тех же данных (поскольку блокировки отсутствуют, ничто не помешает это сделать). Об этом говорит сайт https://intellect.icu . Тогда та транзакция, которая зафиксируется первой, сохранит свои изменения в основной БД, а остальные параллельные транзакции окажется невозможно зафиксировать (так как это приведет к потере обновления первой транзакции). Единственное, что может в такой ситуации СУБД — это откатить остальные транзакции и выдать сообщение об ошибке «Запись уже изменена».

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

Repeatable read (повторяемость чтения)

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

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

Serializable (упорядочиваемость)

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

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

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

Так, Oracle в принципе не поддерживает нулевой уровень, так как его реализация транзакций исключает «грязные чтения», и формально не позволяет устанавливать уровень Repeatable read, то есть поддерживает только Read committed (по умолчанию) и Serializable. При этом на уровне отдельных команд он, фактически, гарантирует повторяемость чтения (если команда SELECT в первой транзакции выбирает из базы набор строк, и в это время параллельная вторая транзакция изменяет какие-то из этих строк, то результирующий набор, полученный первой транзакцией, будет содержать неизмененные строки, как будто второй транзакции не было). Также Oracle поддерживает так называемые READ-ONLY транзакции, которые соответствуют Serializable, но при этом не могут сами изменять данные.

Microsoft SQL Server поддерживает все четыре стандартных уровня изоляции транзакций, а дополнительно — уровень SNAPSHOT, находящийся между Repeatable read и Serialized. Транзакция, работающая на данном уровне, видит только те изменения данных, которые были зафиксированы до ее запуска, а также изменения, внесенные ею самой, то есть ведет себя так, как будто получила при запуске моментальный снимок данных БД и работает с ним.

Поведение при различных уровнях изолированности

«+» — предотвращает, «-» — не предотвращает.

Уровень изоляции Фантомное чтение Неповторяющееся чтение «Грязное» чтение Потерянное обновление
SERIALIZABLE + + + +
REPEATABLE READ - + + +
READ COMMITTED - - + +
READ UNCOMMITTED - - - +

Уровень изолированности транзакций, феномены(аномалии) данных

MySQL: уровни изоляции транзакций


Есть таблица

CREATE TABLE test (id INT, value VARCHAR(255)) ENGINE=InnoDB;


Что по Вашему покажет этот запрос?

START TRANSACTION;
INSERT INTO test(id, value) VALUES (1, 'test'), (2, 'test 2');
SELECT * FROM test;
COMMIT;
SELECT * FROM test;



А что покажет простейший SELECT во время выполнения текущей транзакции? Не ясно. Вот и придумали такие правила.


Первый READ UNCOMMITTED


Рассмотрим транзакцию выше. После INSERT данные сразу-же станут доступны для чтения. Тоесть еще до вызова COMMIT вне транзакции можно получить только что добавленные данные. В английской литературе это называется dirty read («грязное чтение»). Этот уровень редко используется на практике, да вообще редко кто меняет эти самые уровни.

Второй READ COMMTITED


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

Третий REPEATABLE READ


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

И последний SERIALIZABLE


На данном уровне MySQL блокирует каждую строку над которой происходит какое либо действие, это исключает появление проблемы «фантомов». На самом деле смысла использовать этот уровень нет, т.к. InnoDB и менее популярный Falcon решают эту проблему.

Увидеть текущий уровень изоляции

SHOW VARIABLES LIKE '%tx_isolation%';


Установить

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

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

SELECT @@global.tx_isolation;
SELECT @@tx_isolation;

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

Подробное описание каждого уровня изоляции в InnoDB:

  • READ UNCOMMITTED Также называется "грязным чтением": неблокирующиеся выборки (SELECT) выполняются таким образом, что мы не видим возможные ранние версии записи; таким образом они "несогласованно" читаются в этом уровне изоляции; в остальных случаях этот уровень работает также как и READ COMMITTED.

  • READ COMMITTED Нечто похожее на уровень изоляции Oracle. Все выражения SELECT ... FOR UPDATE и SELECT ... LOCK IN SHARE MODE блокируют только индексные записи и не блокируют интервал перед ними. Поэтому они позволяют свободно добавлять новые записи после заблокированных. UPDATE и DELETE, которые используют уникальный индекс и уникальные условия поиска, блокируют только найденную индексную запись, и не блокируют интервал перед ней. Но в UPDATE и DELETEдиапазонного типа в InnoDB должны установить блокировку следующего ключа или интервальную блокировку и блокировать добавления другими пользователями в интервал, покрытый диапазоном. Это необходимо, т.к. "фантомные строки" должны быть блокированы для успешной работы репликации и восстановления в MySQL.Согласованное чтение работает как и в Oracle: каждое согласованное чтение, даже внутри одной транзакции, устанавливает и читает свой собственный снимок.

  • REPEATABLE READ Этот уровень изоляции используется в InnoDB по умолчанию. SELECT ... FOR UPDATE, SELECT ... LOCK IN SHARE MODE, UPDATE, и DELETE, которые используют уникальные индексы и уникальное условие поиска блокируют только найденную индексную запись и не блокируют интервал перед ней. В остальных случаях эта операция использует блокировку следующего ключа, блокирует диапазон индексов, просканированных блокировкой следующего ключа или интервальной, и блокирует новые добавления другими пользователями.

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

  • SERIALIZABLE Этот уровень похож на предыдущий, но простые SELECT преобразовываются в SELECT ... LOCK IN SHARE MODE.

Уровень изолированности транзакций, феномены(аномалии) данных

Уровень изолированности транзакций, феномены(аномалии) данных

Уровень изолированности транзакций, феномены(аномалии) данных

Уровень изолированности транзакций, феномены(аномалии) данных

Уровень изолированности транзакций, феномены(аномалии) данных

Уровень изолированности транзакций, феномены(аномалии) данных

Уровень изолированности транзакций, феномены(аномалии) данных

Уровень изолированности транзакций, феномены(аномалии) данных

Уровень изолированности транзакций, феномены(аномалии) данных

Уровень изолированности транзакций, феномены(аномалии) данных

Deadlocks (Взаимоблокировки)

Уровень изолированности транзакций, феномены(аномалии) данных

Уровень изолированности транзакций, феномены(аномалии) данных

Уровни изолированности и ACID

Уровень изолированности транзакций, феномены(аномалии) данных

По сути транзакции характеризуются следующими четырьмя свойствами (также известными как ACID):

  1. Атомарность
  2. Консистентность
  3. Изоляция
  4. Долговечность

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

Режим неявной транзакции известен так же как режим autocommit.

Для enterprise систем режим автокоммита следует избегать из-за серьезных проблем с производительностью, и данный режим не позволит включать группу множественных DML в единую атомарную «единицу работы».

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

Атомарность

Атомарность позволяет объединить единые и независимые операции в «единицу работы», которая работает по принципу «все-или-ничего», успешно выполняющаяся только если все содержащиеся операции успешно выполнятся.

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

Консистентность (согласованность)

Консистентность означает что все требования уникальности были соблюдены для каждой совершенной транзакции. Это подразумевает, что требования по всем ключам (primary и foreign key), типам данных, триггерам успешно пройдены и не было найдено нарушений требования уникальности.

Изоляция

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

Долговечность

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

Для систем сообщений, как JMS, транзакции не являются обязательными. Именно по этой причине в спецификации есть режимы подтверждения вне транзакций.

Операции с файловой системой обычно не контролируются, но если бизнес-требования требуют транзакций для операций с файлами, Вы можете использовать инструмент, такой как XADisk.

В то время как для файловых систем и систем передачи сообщений использование транзакций опционально, то для БД контроль за транзакциями обязателен.

Уровни изолированности

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

Стандарты SQL определяют 4 уровня изолированности:

  • READ_UNCOMMITTED
  • READ_COMMITTED
  • REPEATABLE_READ
  • SERIALIZABLE

Все уровни, кроме SERIALIZABLE уровня подвержены аномалии данных (феномен), которые могут произойти согласно следующей схеме:

Isolation Level Dirty read Non-repeatable read Phantom read
READ_UNCOMMITTED — чтение незавершенных транзакций да да да
READ_COMMITTED — чтение завершенных транзакций нет да да
REPEATABLE_READ — повторяемое чтение нет нет да
SERIALIZABLE — последовательное чтение нет нет нет

Феномены

Давайте обсудим каждую из аномалий.

Dirty Read («Грязное» чтение)

Уровень изолированности транзакций, феномены(аномалии) данных

«Грязное» чтение происходит когда транзакция может прочитать незаконченные изменения некоторой другой выполняемой транзакции. Явление случается из-за того что нет блокировки предотвращающей это. На изображении сверху можно увидеть что вторая транзакция использует неконсистентное значение первой транзакции, которая впоследствии подверглась «откату». Так как данный эффект возможен только при минимальном уровне изоляции, а по умолчанию используется более высокий уровень изоляции (READ COMMITTED), то в скрипте чтения данных уровень изоляции будет явно установлен как READ UNCOMMITTED. Если вернуть уровень изоляции по умолчанию (READ COMMITTED) для транзакции 2, то поведение поменяется.

Non-repeatable read (Неповторяющееся чтение)

Уровень изолированности транзакций, феномены(аномалии) данных

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

Транзакция 1 Транзакция 2

SET TRANSACTION ISOLATION LEVEL READ COMMITTED
—SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
BEGIN TRAN;

SELECT Value
FROM Table1
WHERE Id = 1;WAITFOR DELAY ’00:00:10′;SELECT Value
FROM Table1
WHERE Id = 1;

COMMIT;

BEGIN TRAN;

UPDATE Table1
SET Value = 42
WHERE Id = 1;

COMMIT TRAN;

Результат для READ COMMITTED Value = 1
Value = 42
Мгновенное выполнение
Результат для REPEATABLE READ Value = 1
Value = 1
Ожидание завершения транзакции 1

Phantom read (Фантомное чтение)

Уровень изолированности транзакций, феномены(аномалии) данных

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

Следовательно, мы используем устравшие данные, который могут оказать негативное влияние на работу системы. Это предотвращается с помощью использования блокировки по диапазону или блокировки предикатами.

Транзакция 1 Транзакция 2
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
—SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN;

SELECT * FROM Table1

WAITFOR DELAY ’00:00:10′

SELECT * FROM Table1

COMMIT;

BEGIN TRAN;

INSERT INTO Table1 (Value)
VALUES(100)
COMMIT TRAN;

Результат для REPEATABLE READ: — первый SELECT
ID: 1; Value: 1
— второй SELECT
ID: 1; Value: 1
ID: 2; Value: 100
Мгновенное выполнение
Результат для SERIALIZABLE: — первый SELECT
ID: 1; Value: 1
— второй SELECT
ID: 1; Value: 1
Ожидание завершения транзакции 1

Уровни изолированности по умолчанию

Даже если SQL стандарт обязывает использовать уровень изоляции SERIALIZABLE, большинство СУБД используют разный уровень по умолчанию.

СУБД Уровень по умолчанию
Oracle READ_COMMITTED
MySQL REPEATABLE_READ
Microsoft SQL Server READ_COMMITTED
PostgreSQL READ_COMMITTED
DB2 CURSOR STABILITY

Обычно, READ_COMMITED является правильным выбором, поскольку даже SERIALIZABLE не может защитить Вас от потери обновлений во время выполнения чтения/записей в разных транзакций и веб-реквестов. Вы должны принять во внимание эту информацию при принятии решения об уровне изоляции в требованиях enterprise систем.

Сценарии возникновения нежелательных эффектов

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

Таблица EXAMPLE

id INTEGER dat INTEGER
1 100
2 110
3 120
4 130

5.3.1 Потерянные изменения

Транзакция T1 Шаг Транзакция T2
UPDATE example SET dat=dat+1 WHERE id=1 1
2 UPDATE example SET dat=dat+1 WHERE id=1
COMMIT 3
4 COMMIT
SELECT * FROM example 5

Если потерянные изменения допускаются, то сценарий выполнится без ошибок и блокировок. На шаге 5 будет выбрано:

        id         dat 
---------- -----------
         1         111
         2         110
         3         120
         4         130

5.3.2 Грязное чтение

Транзакция T1 Шаг Транзакция T2
1 UPDATE example SET dat=111 WHERE id=1
UPDATE example SET dat= (SELECT dat FROM example WHERE id=1) WHERE id=2 2
SELECT * FROM example 3
4 ROLLBACK
5 SELECT * FROM example

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

На шаге 3 будет выбрано:

        id         dat 
---------- -----------
         1         111
         2         111
         3         120
         4         130

На шаге 5 будет выбрано:

        id         dat 
---------- -----------
         1         100
         2         111
         3         120
         4         130

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

Транзакция T1 Шаг Транзакция T2
SELECT * FROM example WHERE id=1 1
[COMMIT] 2 UPDATE example SET dat=111 WHERE id=1
3 COMMIT
SELECT * FROM example WHERE id=1 4
COMMIT 5

Если неповторяющееся чтение допускается, то сценарий выполнится без ошибок и блокировок. Операцию COMMIT в транзакции T1 на шаге 2 выполнять не придется.

На шаге 1 будет выбрано:

        id         dat 
---------- -----------
         1         100

На шаге 4 будет выбрано:

        id         dat 
---------- -----------
         1         111

Если выполнить операцию COMMIT на шаге 2, то результаты будут те же, что и без нее, но здесь уже не будет эффекта неповторяющегося чтения, так как разные результаты будут прочитаны уже в разных транзакциях.

5.3.4 Фантом

Транзакция T1 Шаг Транзакция T2
SELECT * FROM example WHERE dat>110 1
[COMMIT] 2 INSERT INTO example VALUES(5,10)
3 COMMIT
SELECT * FROM example WHERE dat>110 4
COMMIT 5

Если допускаются фантомы, то сценарий выполнится без ошибок и блокировок. Операцию COMMIT в транзакции T1 на шаге 2 выполнять не придется.

На шаге 1 будет выбрано:

        id         dat 
---------- -----------
         3         120
         4         130

На шаге 4 будет выбрано: id dat ---------- ----------- 3 120 4 130 5 150

Вау!! 😲 Ты еще не читал? Это зря!

Выводы из данной статьи про уровень изолированности транзакций указывают на необходимость использования современных методов для оптимизации любых систем. Надеюсь, что теперь ты понял что такое уровень изолированности транзакций, транзакции, аномалии данных, феномен данных и для чего все это нужно, а если не понял, или есть замечания, то не стесняйся, пиши или спрашивай в комментариях, с удовольствием отвечу. Для того чтобы глубже понять настоятельно рекомендую изучить всю информацию из категории Базы данных, знаний и хранилища данных. Big data, СУБД и SQL и noSQL

создано: 2016-04-15
обновлено: 2021-12-01
132612



Рейтиг 9 of 10. count vote: 2
Вы довольны ?:


Поделиться:

Найди готовое или заработай

С нашими удобными сервисами без комиссии*

Как это работает? | Узнать цену?

Найти исполнителя
$0 / весь год.
  • У вас есть задание, но нет времени его делать
  • Вы хотите найти профессионала для выплнения задания
  • Возможно примерение функции гаранта на сделку
  • Приорететная поддержка
  • идеально подходит для студентов, у которых нет времени для решения заданий
Готовое решение
$0 / весь год.
  • Вы можите продать(исполнителем) или купить(заказчиком) готовое решение
  • Вам предоставят готовое решение
  • Будет предоставлено в минимальные сроки т.к. задание уже готовое
  • Вы получите базовую гарантию 8 дней
  • Вы можете заработать на материалах
  • подходит как для студентов так и для преподавателей
Я исполнитель
$0 / весь год.
  • Вы профессионал своего дела
  • У вас есть опыт и желание зарабатывать
  • Вы хотите помочь в решении задач или написании работ
  • Возможно примерение функции гаранта на сделку
  • подходит для опытных студентов так и для преподавателей



Комментарии

Марина
14-02-2022
спасибо

Оставить комментарий
Если у вас есть какое-либо предложение, идея, благодарность или комментарий, не стесняйтесь писать. Мы очень ценим отзывы и рады услышать ваше мнение.
To reply

Базы данных, знаний и хранилища данных. Big data, СУБД и SQL и noSQL

Термины: Базы данных, знаний и хранилища данных. Big data, СУБД и SQL и noSQL