В чем разница между невоспроизводимым чтением и фантомным чтением?
в чем разница между неповторяемым чтением и фантомным чтением?
прочитал изоляция (системы баз данных) статья из Википедии, но у меня есть некоторые сомнения. В приведенном ниже примере, что произойдет:неповторяемое чтение и Фантом читать?
Транзакция ASELECT 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 выполняет транзакцию и фиксирует.
- неповторяемое чтение: строка A, которую пользователь A запросил, имеет другое значение во второй раз.
- Phantom read: все строки в запросе имеют одинаковое значение до и после, но выбираются разные строки (потому что B удалил или вставил некоторые). Образец:
select sum(x) from table;
вернет другой результат, даже если ни одна из затронутых строк не была обновлена, если строки были добавлены или удалены.В приведенном выше примере,какой уровень изоляции будет использоваться?
какой уровень изоляции зависит от вашего приложения. Существует высокая стоимость "лучшего" уровня изоляции (например, снижение параллелизма).
в вашем примере у вас не будет фантомного чтения, потому что вы выбираете только из a одна строка (определяется первичным ключом). Вы можете иметь неповторяемые чтения, поэтому, если это проблема, вы можете иметь уровень изоляции, который предотвращает это. В Oracle транзакция A также может выдать выбор для обновления, а затем транзакция B не может изменить строку, пока A не будет выполнена.
простой способ, который мне нравится думать об этом:
Как неповторяемые, так и фантомные чтения связаны с операциями изменения данных из другой транзакции, которые были зафиксированы после начала транзакции, а затем прочитаны вашей транзакцией.
неповторяемые чтения - это когда ваша транзакция читает committed обновления из другой транзакции. Одна и та же строка теперь имеет другие значения, чем при вашей транзакции началось.
фантомные чтения похожи, но при чтении из committed вставка и/или удалить из другой транзакции. Есть новые строки или строки, которые исчезли с момента начала транзакции.
грязное чтение как к неповторяемым и фантомным считываниям, но относятся к чтению незафиксированных данных и происходят, когда обновление, вставка или удаление из другой транзакции считывается, а другая транзакция еще не выполнена зафиксировал данные. Он считывает данные "в процессе", которые могут быть неполными и никогда не будут зафиксированы.
существует разница в реализации между этими двумя уровнями изоляции видов.
Для "неповторяемого чтения" необходима блокировка строк.
Для "фантомного чтения" требуется блокировка области видимости, даже блокировка таблицы.
Мы можем реализовать эти два уровня с помощью двухфазной блокировки протокол.
грязное чтение: чтение незафиксированных данных из транзакции anouther.
неповторяемое чтение: чтение данных, полученных из запроса на обновление, из транзакции anouther.
Phantom read: чтение полученных данных из запроса вставки или удаления из транзакции anouther.
обратите внимание, что обновления могут быть более частым заданием в некоторых usecases, а не фактической вставкой или удалением - в таких случаях опасность невоспроизводимых чтений остается только-фантомные чтения не являются возможно в таких случаях. Поэтому обновления обрабатываются иначе, чем INSERT-DELETE, и соответствующая аномалия также называется по-другому.
существует также дополнительная стоимость обработки, связанная с обработкой для вставки-удаления , а не просто обрабатывать обновления.
уровень изоляции TRANSACTION_READ_UNCOMMITTED ничего не предотвращает. Его нулевой уровень изоляции.
уровень изоляции TRANSACTION_READ_COMMITTED предотвращает только один, т. е. Грязный читает.
уровень изоляции TRANSACTION_REPEATABLE_READ предотвращает две аномалии: грязные чтения и неповторяемые чтения.
уровень изоляции TRANSACTION_SERIALIZABLE предотвращает все три аномалии: грязные чтения, неповторяемые чтения и фантомные чтения.
тогда почему бы просто не установить транзакцию СЕРИАЛИЗУЕМОЙ во все времена ??
Ну, ответ на этот вопрос таков: СЕРИАЛИЗУЕМАЯ настройка делает транзакции очень медленными , чего мы снова не хотим.
на самом деле время транзакции расходуется в следующем темпе:
SERIALIZABLE > REPEATABLE_READ > READ_COMMITTED > READ_UNCOMMITTED .
Так что READ_UNCOMMITTED установка является самым быстрым .
на самом деле нам нужно проанализировать usecase и решить уровень изоляции, чтобы мы оптимизировали время транзакции, а также предотвратили большинство аномалий.
обратите внимание, что базы данных по умолчанию имеют параметр REPEATABLE_READ.
Как поясняется в в этой статье на Неповторяемое Чтение аномалия выглядит следующим образом:
- Алиса и Боб запускают две транзакции базы данных.
- Боб читает запись post и значение столбца title-Это транзакции.
- Алиса изменяет название данной записи post на значение ACID.
- Алиса совершает свою транзакцию базы данных.
- если Боба перечитывает запись post, он будет наблюдать другую версию этой строки таблицы.
на в этой статье о Фантом Читать, вы можете видеть, что эта аномалия может произойти следующим образом:
- Алиса и Боб запускают две транзакции базы данных.
- Боб читает все записи post_comment, связанные с строкой post со значением идентификатора 1.
- Алиса добавляет новая запись post_comment, связанная со строкой post, имеющей значение идентификатора 1.
- Алиса совершает свою транзакцию базы данных.
- если Боб перечитывает записи post_comment, имеющие значение столбца post_id, равное 1, он будет наблюдать другую версию этого результирующего набора.
пока Неповторяемое Чтение применяется к одной строке,Фантом Читать речь идет о диапазоне записей, которые удовлетворяют a заданные критерии фильтрации запросов.
в системе с неповторяемыми считываниями результат второго запроса транзакции A будет отражать обновление в транзакции B-он увидит новую сумму.
в системе, которая позволяет фантомное чтение, если транзакция 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 проверить таблицу, чтобы убедиться, что нет записи, но эти данные были вставил, так что может произойти некоторые ошибки. Мы называем это фантомным чтением.