Вопрос по isolation-level, oracle, transaction-isolation, database, transactions – В чем разница между неповторяющимся чтением и фантомным чтением?

112

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

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

Transaction A
SELECT ID, USERNAME, accountno, amount FROM USERS WHERE ID=1
OUTPUT:
1----MIKE------29019892---------5000
Transaction B
UPDATE USERS SET amount=amount+5000 where ID=1 AND accountno=29019892;
COMMIT;
Transaction A
SELECT ID, USERNAME, accountno, amount FROM USERS WHERE ID=1

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

Ваш Ответ

8   ответов
124

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

A non-repeatable read occurs, when during the course of a transaction, a row is retrieved twice and the values within the row differ between reads.

а также

A phantom read occurs when, in the course of a transaction, two identical queries are executed, and the collection of rows returned by the second query is different from the first.

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

User A runs the same query twice. In between, User B runs a transaction and commits. Non-repeatable read: The A row that user A has queried has a different value the second time. Phantom read: All the rows in the query have the same value before and after, but different rows are being selected (because B has deleted or inserted some). Example: select sum(x) from table; will return a different result even if none of the affected rows themselves have been updated, if rows have been added or deleted.

In the above example,which isolation level to be used?

Какой уровень изоляции вам нужен, зависит от вашего приложения. «Лучше» дорого обходится уровень изоляции (например, снижение параллелизма).

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

Я не совсем понимаю логику такого синтаксиса ...NON-repeatable чтение происходит, когда чтениеrepeated (и получено другое значение) ??! ...
@Thilo Какой-нибудь реальный пример использования, где repeatable-read может создать проблемы и где это необходимо?
Что если PK будет изменен в другой транзакции? Может ли это привести к фантомному чтению? (В большинстве случаев странная вещь, но не невозможная.)
@serhio & quot; неповторяемый & quot; относится к тому факту, что вы можете прочитать значение один раз и получить x в качестве результата, а затем снова прочитать и получить y в качестве результата, так что вы не можете повторить (неповторяемые) одинаковые результаты из двух отдельных запросов одной и той же строки, потому что это значение строки было обновлено между чтениями.
90

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

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

Призрачные чтения похожи, но при чтении из совершенныхINSERTS и / илиDELETES из другой транзакции. Есть новые строки или строки, которые исчезли с момента начала транзакции.

Грязные чтенияsimilar к неповторяемым и фантомным чтениям, но относятся к чтению НЕКОММИТИРОВАННЫХ данных и происходят, когда читается UPDATE, INSERT или DELETE из другой транзакции, а другая транзакция еще НЕ зафиксировала данные. Это чтение "в процессе" данные, которые могут не быть полными и никогда не будут переданы.

Я поражен (или говорю, что не верю). Грязное чтение: чтение измененных данных (другой транзакцией), которые на самом деле не зафиксированы или могут никогда не быть зафиксированы. Где, возможно, этот сценарий может быть использован? (Это не я вам не верю - На самом деле, я не понял концепцию должным образом) - Пожалуйста, не возражайте (возможно, вы сможете понять разочарование новичка)
@BateTech UPDATE или DELETE могут иметь место для неповторяющихся чтений, или это только ОБНОВЛЕНИЕ?
Что, если за удалением следует вставка, которая не может быть использована для эффективного обновления?
Это связано с уровнями изоляции транзакций и параллелизмом. Используя уровень изоляции по умолчанию, вы не получите грязное чтение, и в большинстве случаев вы хотите избежать грязного чтения. Существуют уровни изоляции или подсказки запросов, которые позволяют выполнять грязное чтение, что вsome Случаи - приемлемый компромисс для достижения более высокого уровня параллелизма или необходимы из-за пограничного случая, такого как устранение неполадок в текущей транзакции из другого соединения. Хорошо, что идея грязного чтения не проходит «тест на запах». для вас, как правило, их следует избегать, но у них есть цель.
@DiponRoy отличный вопрос. Блокировка, реализованная при использовании изоляции с повторяющимся чтением (RR), должна предотвращать удаление в выбранных строках. Я видел разные определения двух уровней iso в течение многих лет, в основном говоря, что фантом - это изменение в возвращаемых строках collection / #, а RR - это та же самая изменяемая строка. Я только что проверил обновленную документацию MS SQL говорит, что удаление может вызвать не RR (docs.microsoft.com/en-us/sql/odbc/reference/develop-app/… ) так что я думаю, что было бы безопасно группировать удаления также в категории RR
5

Неповторяемое чтение: чтение данных COMMITED из запроса UPDATE из другой транзакции.

Фантомное чтение: чтение данных COMMITED из запроса INSERT или DELETE из другой транзакции.

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

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

Уровень изоляции TRANSACTION_READ_UNCOMMITTED ничего не мешает. Это нулевой уровень изоляции.

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

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

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

Тогда почему бы просто не установить транзакцию SERIALIZABLE во все времена ??

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

На самом деле затраты времени транзакции в следующем размере:

SERIALIZABLE & gt; REPEATABLE_READ & gt; READ_COMMITTED & gt; READ_UNCOMMITTED.

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

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

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

ОБНОВЛЕНИЕ или УДАЛЕНИЕ оба могут иметь место для неповторяющихся чтений, или это только ОБНОВЛЕНИЕ?
ОБНОВЛЕНИЕ или УДАЛЕНИЕ оба могут иметь место для неповторяющихся чтений
9

Эта статья,Non-Repeatable Read Аномалия выглядит следующим образом:

enter image description here

Alice and Bob start two database transactions. Bob’s reads the post record and title column value is Transactions. Alice modifies the title of a given post record to the value of ACID. Alice commits her database transaction. If Bob’s re-reads the post record, he will observe a different version of this table row.

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

enter image description here

Alice and Bob start two database transactions. Bob’s reads all the post_comment records associated with the post row with the identifier value of 1. Alice adds a new post_comment record which is associated with the post row having the identifier value of 1. Alice commits her database transaction. If Bob’s re-reads the post_comment records having the post_id column value equal to 1, he will observe a different version of this result set.

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

превосходная визуализация @Vlad
Спасибо. Я рад, что вам понравилось.
7


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

Для реализации повторяемого чтения или сериализации нет необходимости использовать блокировку строк.
1

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

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

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

4

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

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

Я не думаю, что объяснение фантомного чтения правильное. Вы можете получить фантомное чтение, даже если данные без фиксации никогда не видны. Смотрите пример в Википедии (ссылка в комментариях выше).
0

фантомное чтение.

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

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

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

Похожие вопросы