В чем разница между неповторяющимся чтением и фантомным чтением?

В чем разница между неповторяемым чтением и phantom read?

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

Транзакция A
SELECT ID, USERNAME, accountno, amount FROM USERS WHERE ID=1
ВЫВОД:
1----MIKE------29019892---------5000
Транзакция B
UPDATE USERS SET amount=amount+5000 where ID=1 AND accountno=29019892;
COMMIT;
Транзакция A
SELECT ID, USERNAME, accountno, amount FROM USERS WHERE ID=1

Еще одно сомнение заключается в том, что в приведенном выше примере должен использоваться уровень изоляции? И почему?

Ответ 1

Из Википедии (в котором есть большие и подробные примеры для этого):

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

и

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

Простые примеры:

  • Пользователь A дважды выполняет один и тот же запрос.
  • В промежутке между Пользователем B выполняется транзакция и выполняется.
  • Непрерывное чтение: строка, которую запросил пользователь A, имеет второй раз.
  • Phantom read: Все строки запроса имеют одно и то же значение до и после, но выбираются разные строки (поскольку B удалил или вставил некоторые). Пример: select sum(x) from table; возвращает другой результат, даже если ни одна из затронутых строк не была обновлена, если строки были добавлены или удалены.

В приведенном выше примере, какой уровень изоляции будет использоваться?

Какой уровень изоляции вам нужен, зависит от вашего приложения. Существует высокая стоимость "лучшего" уровня изоляции (например, уменьшенная concurrency).

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

Ответ 2

Простым способом, который мне нравится думать, является:

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

Непрерывные чтения - это когда ваша транзакция считывает заверенные ОБНОВЛЕНИЯ из другой транзакции. Такая же строка имеет разные значения, чем при начале транзакции.

Phantom чтения аналогичны, но при чтении из объявленных ВСТАВКИ и/или DELETES из другой транзакции. Появляются новые строки или строки, которые исчезли с момента начала транзакции.

Грязные чтения похожи на неповторяющиеся и phantom чтения, но относятся к чтению данных UNCOMMITTED и происходят при чтении UPDATE, INSERT или DELETE из другой транзакции, а другая транзакция еще не передала данные, Он считывает данные "в процессе", которые могут быть неполными и никогда не могут быть выполнены.

Ответ 3

Как объясняется в этой статье, аномалия неповторяемого чтения выглядит следующим образом:

enter image description here

  1. Алиса и Боб запускают две транзакции базы данных.
  2. Бобс читает запись записи и заголовок столбца имеет значение Транзакции.
  3. Алиса изменяет заголовок данной записи сообщения на значение ACID.
  4. Алиса совершает свою транзакцию базы данных.
  5. Если Бобс перечитает запись, он увидит другую версию этой строки таблицы.

В этой статье о Phantom Read вы можете увидеть, что эта аномалия может произойти следующим образом:

enter image description here

  1. Алиса и Боб запускают две транзакции базы данных.
  2. Бобс читает все записи post_comment, связанные со строкой сообщения со значением идентификатора 1.
  3. Алиса добавляет новую запись post_comment, которая связана со строкой записи, имеющей значение идентификатора 1.
  4. Алиса совершает свою транзакцию базы данных.
  5. Если Бобс перечитывает записи post_comment со значением столбца post_id, равным 1, он будет наблюдать другую версию этого набора результатов.

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

Ответ 4

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

  • Грязное чтение: считывание НЕКОММЕДИРОВАННЫХ данных из другой транзакции
  • Неповторяемые операции чтения: чтение данных COMMITTED из запроса UPDATE из другой транзакции
  • Фантомное чтение: чтение данных COMMITTED из запроса INSERT или DELETE из другой транзакции

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

Также мы можем заметить, что ОБНОВЛЕНИЕ может быть более частой работой в большинстве случаев использования, а не фактической ВСТАВКОЙ или УДАЛЕНИЯМИ (в таких случаях остается опасность только неповторяющихся чтений - фантомное чтение в этих случаях невозможно). Вот почему ОБНОВЛЕНИЯ обрабатываются иначе, чем INSERT-DELETE, и результирующая аномалия также называется по-разному.

Существует также дополнительная стоимость обработки, связанная с обработкой для INSERT-DELETE, а не просто с обработкой ОБНОВЛЕНИЙ.


Преимущества разных уровней изоляции

  • READ_UNCOMMITTED ничего не мешает. Это нулевой уровень изоляции
  • READ_COMMITTED предотвращает только один, то есть Грязное чтение
  • REPEATABLE_READ предотвращает две аномалии: грязное чтение и неповторяемое чтение
  • SERIALIZABLE предотвращает все три аномалии: грязные чтения, неповторяющиеся чтения и фантомные чтения

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

Фактически потребление времени транзакции происходит в следующем размере:

SERIALIZABLE > REPEATABLE_READ > READ_COMMITTED > READ_UNCOMMITTED

Поэтому установка READ_UNCOMMITTED является самой быстрой.


Резюме

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

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

Ответ 5

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

Ответ 6

В системе с неповторяющимися чтениями результат второго запроса транзакции будет отражать обновление в транзакции B - он увидит новую сумму.

В системе, которая позволяет читать phantom, если Transaction B должен был вставить новую строку с ID = 1, Transaction A увидит новую строку при выполнении второго запроса; то есть phantom чтение является частным случаем не повторяемого чтения.

Ответ 7

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

Если "строка извлекается дважды, а значения внутри строки отличаются друг от друга", то они не являются одной и той же строкой (не такой же кортеж в правильной речи RDB), и тогда действительно по определению также случай, сбор строк, возвращаемых вторым запросом, отличается от первого ".

Что касается вопроса "какой уровень изоляции следует использовать", тем больше ваши данные имеют жизненно важное значение для кого-то, где-то, тем больше будет случай, когда Serializable является вашим единственным разумным вариантом.

Ответ 8

Я думаю, что есть некоторая разница между неповторяющимся чтением и фантомным чтением.

Неповторяемый означает, что есть транзакция буксировки A и B. Если B может заметить модификацию A, поэтому может произойти грязное чтение, поэтому мы позволяем B заметить модификацию A после фиксации A.

Есть новая проблема: мы позволяем B заметить изменение A после фиксации A, это означает, что A изменяет значение строки, которое содержит B, когда-то B снова прочитает строку, поэтому B получит новое значение, отличное от того, когда мы в первый раз получить, мы называем это "Неповторимым", чтобы разобраться с проблемой, мы позволяем B вспомнить что-то (потому что я еще не знаю, что запомнится), когда начнется B.

Давайте подумаем о новом решении, мы можем заметить, что есть и новая проблема, потому что мы позволяем B запомнить что-то, поэтому, что бы ни случилось в A, B не может быть затронуто, но если B хочет вставить некоторые данные в таблицу и B проверьте таблицу, чтобы убедиться, что нет записи, но эти данные были вставлены буквой A, поэтому может произойти какая-то ошибка. Мы называем это фантомом.

Ответ 9

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