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

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

прочитал изоляция (системы баз данных) статья из Википедии, но у меня есть некоторые сомнения. В приведенном ниже примере, что произойдет:non-repeatable читать и Фантом читать?

Транзакция 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;
сделки А
SELECT ID, USERNAME, accountno, amount FROM USERS WHERE ID=1

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

8 ответов


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

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

и

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

простой пример:

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

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

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

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


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

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

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

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

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


существует разница в реализации между этими двумя уровнями изоляции видов.
Для "non-repeatable прочитанного", row-locking необходим.
Для "phantom read", scoped-блокировка необходима, даже блокировка таблицы.
Мы можем реализовать эти два уровня с помощью двухфазной блокировки протокол.


Dirty read: чтение незафиксированных данных из транзакции anouther.

non-repeatable read: чтение данных из запроса на обновление из транзакции anouther.

Phantom read: чтение данных из запроса вставки или удаления из транзакции anouther.

обратите внимание, что обновления могут быть более частым заданием в некоторых usecases, а не фактической вставкой или удалением - в таких случаях опасность неповторяющихся чтений остается только-фантомные чтения не в таких случаях это возможно. Вот почему обновления обрабатываются иначе, чем INSERT-DELETE, и соответствующая аномалия также называется по-разному.

существует также дополнительная стоимость обработки, связанная с обработкой для INSERT-DELETS, а не просто обработкой обновлений.

уровень изоляции TRANSACTION_READ_UNCOMMITTED ничего не предотвращает. Его нулевой уровень изоляции.

уровень изоляции TRANSACTION_READ_COMMITTED предотвращает только один, т. е. Грязный читает.

уровень изоляции TRANSACTION_REPEATABLE_READ предотвращает две аномалии: грязные чтения и невоспроизводимые чтения.

уровень изоляции TRANSACTION_SERIALIZABLE предотвращает все три аномалии: грязные чтения, невоспроизводимые чтения и фантомные чтения.

тогда почему бы просто не установить СЕРИАЛИЗУЕМУЮ транзакцию во все времена ??

ну, ответ на вышеуказанный вопрос: СЕРИАЛИЗУЕМАЯ настройка делает транзакции очень медленными, чего мы снова не хотим.

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

СЕРИАЛИЗУЕМЫЙ > REPEATABLE_READ > READ_COMMITTED > READ_UNCOMMITTED .

поэтому параметр READ_UNCOMMITTED является самым быстрым .

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

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


Как поясняется в в этой статье на Non-Repeatable Читать аномалия выглядит следующим образом:

enter image description here

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

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

enter image description here

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

пока Non-Repeatable Читать применяется к одной строке,Фантом Читать о ряде показателей которые удовлетворяют а заданные критерии фильтрации запросов.


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

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


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

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

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


Я думаю, что есть некоторая разница между non-repeateable-read & phantom-read.

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

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

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