В чем разница между неповторяющимся чтением и фантомным чтением?
Я прочитал статью « Изоляция (системы баз данных)» из Википедии , но у меня есть несколько сомнений. Что будет в следующем примере: неповторяющееся чтение и фантомное чтение ?
Транзакция АSELECT ID, USERNAME, accountno, amount FROM USERS WHERE ID=1
ВЫВОД:
1----MIKE------29019892---------5000
Транзакция Б
UPDATE USERS SET amount=amount+5000 where ID=1 AND accountno=29019892;
COMMIT;
Транзакция А
SELECT ID, USERNAME, accountno, amount FROM USERS WHERE ID=1
Другое сомнение заключается в том, какой уровень изоляции следует использовать в приведенном выше примере? И почему?
Ответы:
Из Википедии (где есть отличные и подробные примеры):
и
Простые примеры:
select sum(x) from table;
вернет другой результат, даже если ни одна из затронутых строк не была обновлена, если строки были добавлены или удалены.Какой уровень изоляции вам нужен, зависит от вашего приложения. «Лучший» уровень изоляции обходится дорого (например, снижение параллелизма).
В вашем примере у вас не будет фантомного чтения, потому что вы выбираете только из одной строки (идентифицируемой первичным ключом). У вас могут быть неповторяющиеся чтения, поэтому, если это проблема, вы можете захотеть иметь уровень изоляции, который предотвращает это. В Oracle транзакция A также может выдавать SELECT FOR UPDATE, тогда транзакция B не может изменить строку до тех пор, пока A не будет завершена.
источник
Простой способ мне нравится думать об этом:
И неповторяющиеся, и фантомные чтения имеют отношение к операциям модификации данных из другой транзакции, которые были зафиксированы после начала вашей транзакции, а затем прочитаны вашей транзакцией.
Неповторяемые чтения - это когда ваша транзакция читает подтвержденные ОБНОВЛЕНИЯ из другой транзакции. Теперь та же строка имеет значения, отличные от тех, которые были в начале вашей транзакции.
Phantom читает похожи , но при чтении совершенных INSERTS и / или удалений из другой транзакции. Есть новые строки или строки, которые исчезли с момента начала транзакции.
Грязное чтение аналогично неповторяющемуся и фантомному чтению, но относится к чтению НЕКОММИТИРОВАННЫХ данных и происходит, когда читается UPDATE, INSERT или DELETE из другой транзакции, а другая транзакция еще не зафиксировала данные. Это чтение данных «в процессе», которые могут быть неполными и никогда не быть зафиксированными.
источник
Как объясняется в этой статье , аномалия неповторяемого чтения выглядит следующим образом:
В этой статье о фантомном чтении вы можете увидеть, что эта аномалия может произойти следующим образом:
Таким образом, хотя неповторяемое чтение применяется к одной строке, фантомное чтение относится к диапазону записей, которые удовлетворяют заданным критериям фильтрации запросов.
источник
Читать явления
UPDATE
запроса из другой транзакцииINSERT
илиDELETE
запроса из другой транзакцииПримечание : операторы DELETE из другой транзакции также имеют очень низкую вероятность вызвать неповторяющиеся чтения в некоторых случаях. Это происходит, когда оператор DELETE, к сожалению, удаляет ту же строку, к которой обращалась ваша текущая транзакция. Но это редкий случай, и гораздо менее вероятно, что он произойдет в базе данных, содержащей миллионы строк в каждой таблице. Таблицы, содержащие данные транзакций, обычно имеют большой объем данных в любой производственной среде.
Также мы можем заметить, что ОБНОВЛЕНИЯ могут быть более частой работой в большинстве случаев использования, а не фактической ВСТАВКОЙ или УДАЛЕНИЯМИ (в таких случаях остается опасность только неповторяющихся чтений - фантомные чтения в этих случаях невозможны). Вот почему ОБНОВЛЕНИЯ обрабатываются иначе, чем INSERT-DELETE, и результирующая аномалия также называется по-разному.
Существует также дополнительная стоимость обработки, связанная с обработкой для INSERT-DELETE, а не просто с обработкой ОБНОВЛЕНИЙ.
Преимущества разных уровней изоляции
Тогда почему бы просто не установить транзакцию SERIALIZABLE в любое время? Что ж, ответ на поставленный выше вопрос таков: настройка SERIALIZABLE делает транзакции очень медленными , чего мы опять не хотим.
Фактически потребление времени транзакции происходит в следующем размере:
Поэтому установка READ_UNCOMMITTED является самой быстрой .
Резюме
На самом деле нам нужно проанализировать сценарий использования и определить уровень изоляции, чтобы оптимизировать время транзакции, а также предотвратить большинство аномалий.
Обратите внимание, что базы данных по умолчанию имеют настройку REPEATABLE_READ.
источник
Существует разница в реализации между этими двумя уровнями изоляции.
Для «неповторяемого чтения» необходима блокировка строки.
Для «фантомного чтения» необходима блокировка по объему, даже блокировка по таблице.
Мы можем реализовать эти два уровня, используя протокол двухфазной синхронизации .
источник
В системе с неповторяющимися чтениями результат второго запроса транзакции A будет отражать обновление в транзакции B - он увидит новую сумму.
В системе, которая позволяет фантомное чтение, если Транзакция B вставит новую строку с ID = 1, Транзакция A увидит новую строку при выполнении второго запроса; т.е. фантомное чтение - это особый случай неповторяемого чтения.
источник
Принятый ответ указывает, прежде всего, на то, что так называемое различие между ними на самом деле не имеет никакого значения.
Если «строка извлекается дважды, а значения в строке различаются между операциями чтения», то они не являются одной и той же строкой (не одним и тем же кортежем в правильном выражении RDB), и тогда действительно по определению также имеет место «коллекция строки, возвращаемые вторым запросом, отличаются от первого ".
Что касается вопроса «какой уровень изоляции следует использовать», чем больше ваши данные жизненно важны для кого-то, где-то, тем больше будет случай, когда Serializable - ваш единственный разумный вариант.
источник
Я думаю, что есть некоторая разница между неповторяющимся чтением и фантомным чтением.
Неповторяемый означает, что есть транзакция буксировки A и B. Если B может заметить модификацию A, поэтому может произойти грязное чтение, поэтому мы позволяем B замечать модификацию A после фиксации A.
Существует новая проблема: мы позволяем B заметить изменение A после фиксации A, это означает, что A изменяет значение строки, которое содержит B, когда-то B снова прочитает строку, поэтому B получит новое значение, отличное от того, когда мы в первый раз получить, мы называем это Неповторимым, чтобы иметь дело с проблемой, мы позволяем B вспомнить что-то (потому что я еще не знаю, что еще запомнится), когда начнется B.
Давайте подумаем о новом решении, мы можем заметить, что есть и новая проблема, потому что мы позволяем B запомнить что-то, поэтому, что бы ни случилось в A, B не может быть затронуто, но если B хочет вставить некоторые данные в таблицу и B проверьте таблицу, чтобы убедиться, что нет записи, но эти данные были вставлены буквой A, поэтому может произойти какая-то ошибка. Мы называем это фантомом.
источник
Неповторяемое чтение - это уровень изоляции, а фантомное чтение (чтение зафиксированного значения другими транзакциями) - это концепция (тип чтения, например, грязное чтение или чтение снимка). Неповторяемый уровень изоляции для чтения позволяет фантомное чтение, но не грязное чтение или чтение снимка.
источник