Некоторые пояснения по поводу разных уровней изоляции в транзакции базы данных?

Ниже приводится утверждение из статьи об изоляции Википедии о REPEATABLE READS

На этом уровне изоляции реализация СУБД управления параллелизмом на основе блокировок сохраняет блокировки чтения и записи (полученные для выбранных данных) до конца транзакции. Однако блокировки по диапазону не управляются, поэтому может возникнуть феномен фантомного чтения (см. Ниже).

У меня вопрос, когда транзакция начинается и когда заканчивается соответственно.

Если мы возьмем пример неповторяемых чтений с уровнем изоляции REPEATABLE READS по той же ссылке, согласно моему пониманию, транзакция 1 начинается, когда запускается первый запрос, то есть SELECT * FROM users WHERE id = 1. СУБД будет держать блокировку таблицы пользователей до тех пор, пока транзакция не будет завершена. здесь Под концом, я имею в виду, когда соединение откатывается или фиксируется не после завершения SELECT * FROM users WHERE id = 1. До этого времени будет ждать Транзакция 2 Верно?


Вопрос 2: - Теперь, если мы рассмотрим уровень изоляции и его поведение, как указано ниже (по той же ссылке)

Isolation level     Dirty reads   Non-repeatable   Phantoms
Read Uncommitted    may occur     may occur        may occur
Read Committed      -             may occur        may occur
Repeatable Read     -             may occur        -
Serializable        -             -                -

Насколько я понимаю, наиболее надежным является Serializable, затем Repeatable Read, а затем Read Committed, но все же я видел приложения, использующие Read Committed. Это из-за производительности Serializable и Repeatable Read плохо по сравнению с Read Committed, потому что в сериализуемом он будет последовательным и в случае транзакции придется ждать освобождения блокировки другой транзакцией. Верно? Итак, чтобы получить лучшее из всех трех, мы можем использовать уровень изоляции как Read Committed с SELECT FOR UPDATE (для достижения повторяемого чтения). Не уверен, как мы можем добиться фантомного чтения, если захотим, на случай уровня изоляции прочитанного совершенного?


person M Sach    schedule 14.09.2011    source источник
comment
См. stackoverflow.com/questions/10935850/ для обсуждения SELECT ... FOR UPDATE   -  person Gili    schedule 29.11.2012
comment
Итак, чтобы получить лучшее из всех трех, мы можем использовать уровень изоляции как Read Committed с SELECT FOR UPDATE - это подход уровней персистентности JDO, таких как Datanucleus. Они предоставляют механизм для управления SELECT FOR UPDATE для каждой транзакции. Я считаю, что этот подход даст преимущества механизма блокировки сериализуемых транзакций при использовании более низких типов транзакций.   -  person marcolopes    schedule 10.06.2014
comment
Вы уверены, что повторяющееся чтение может происходить в транзакции с неповторяющимся уровнем изоляции? В этой статье другая таблица - oracle. ru / technetwork / issue-archive / 2010/10-янв /   -  person naXa    schedule 29.12.2015


Ответы (1)


Oracle не поддерживает уровень изоляции REPEATABLE READ. Однако SQL Server это делает - и он устанавливает блокировки для всех строк, выбранных транзакцией, до ее завершения (т. Е. До ее фиксации или отката). Итак, вы правы, это действительно заставит другие транзакции ждать (если они обновляют заблокированные данные) и может нанести ущерб параллелизму.

Что касается вопроса 2: Да, чем выше уровень изоляции, тем хуже будут выполняться ваши параллельные транзакции, потому что им придется ждать, пока будут сняты дополнительные блокировки. Я не совсем понимаю, что вы имеете в виду, говоря о том, что лучше всего использовать все три, используя SELECT FOR UPDATE, потому что SELECT FOR UPDATE установит блокировки строк для всех выбранных строк.

И, наконец, вот цитата из руководства Oracle по фантомам:

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

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


Ссылка:

person NullUserException    schedule 14.09.2011
comment
Я не уверен, что вы имеете в виду, говоря о том, чтобы получить лучшее из всех трех. По сути, я пытаюсь спросить здесь, если мы будем использовать уровень изоляции прочитанного зафиксированного в oracle, мы все равно будем получать как неповторимые, так и фантомные проблемы чтения. Насколько я понимаю, в первую очередь мы не должны называть их проблемами, но это следует рассматривать как правильное поведение, потому что между первой транзакцией, если вторая транзакция совершается, мы должны получить обновленные данные. Продолжение ... - person M Sach; 15.09.2011
comment
продолжение ... Второй вопрос заключается в том, что если мы хотим избежать неповторяющихся и фантомных проблем чтения с чтением, совершенным на оракуле, есть ли способ? На мой взгляд, если мы используем выборку для запроса на обновление, мы можем избавиться от неповторяющихся чтений. Но не знаете, как избежать фантомного чтения? - person M Sach; 15.09.2011