2010-10-27 2 views
155

Я думаю, что вышеупомянутые уровни изоляции настолько похожи. Может ли кто-нибудь описать с некоторыми хорошими примерами, в чем основное отличие?Разница между чтением фиксации и повторяемым чтением

+3

Вы должны расширить вопрос и добавить метки для того, что «уровень изоляции» вы имеете в виду (Java, и т.д.). «Уровень изоляции» - несколько двусмысленный термин, и вы, очевидно, просите ответа для конкретной среды. – jesup

+3

Возможно SQL. Это некоторые из общих уровней изоляции транзакций в SQL. – derobert

+0

Да, это правда, речь идет о SQL. Работая в основном с MSSQL, проблема заключается в том, что после многих исследований в Интернете я могу найти хорошее объяснение основной разности между двумя уровнями изоляции, прочитанными фиксацией и повторяемым чтением. Изменение названия вопроса. – Fore

ответ

376

Прочитано совершенный уровень изоляции, который гарантирует, что все прочитанные данные были совершено на данный момент прочитано. Это просто ограничивает восприятие читателем какого-либо промежуточного, незафиксированного, «грязного» чтения. IT не дает никаких обещаний, что если транзакция перепросит чтение, найдут данные Same, данные могут быть изменены после их чтения.

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

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

Скажите, что у вас есть таблица T со столбцом C с одной строкой в ​​ней, скажем, что она имеет значение «1». И считаю вас есть простая задача, как следующее:

BEGIN TRANSACTION; 
SELECT * FROM T; 
WAITFOR DELAY '00:01:00' 
SELECT * FROM T; 
COMMIT; 

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

  • под READ COMITTED, второй SELECT, может возвращать любой данные. Параллельная транзакция может обновить запись, удалить ее, вставить новые записи. Второй выбор всегда будет видеть данные .
  • under REPEATABLE READ второй SELECT гарантированно увидит строки, которые видели сначала, выбор без изменений. Новые строки могут быть добавлены посредством одновременной транзакции за одну минуту, но существующие строки не могут быть удалены или изменены.
  • под SERIALIZABLE читает, что второй select обязательно должен видеть точно те же строки, что и первый. Никакая строка не может быть изменена или удалена, а новые строки не могут быть вставлены параллельной транзакцией.

Если следовать логике выше вы можете быстро осознать, что SERIALIZABLE сделки, в то время как они могут сделать жизнь проще для вас, всегда полностью блокирует все возможные параллельная работа, так как они требуют, чем никто не может изменять, удалять и не вставьте любую строку. Уровень изоляции транзакции по умолчанию области .Net System.Transactions является сериализуемым, и это обычно объясняет невероятную производительность.

И, наконец, существует также уровень изоляции SNAPSHOT. Уровень изоляции SNAPSHOT обеспечивает те же гарантии, что и сериализуемый, но не требует, чтобы никакая параллельная транзакция не могла модифицировать данные, но каждый читатель видит свою собственную версию мира (это собственный «снимок»). Это упрощает программирование, очень масштабируемое, поскольку оно не блокирует одновременные обновления, но, конечно же, оно имеет цену, а цена - дополнительное потребление ресурсов сервера.

Справочная гласит:

+19

Благодарю вас! Это был очень ясный и информативный ответ. +1 – Phil

+12

Я думаю, что для REPEATABLE READ существует ошибка: вы говорите, что существующие строки не могут быть удалены или изменены, но я думаю, что они могут быть удалены или изменены, потому что повторяемое чтение просто считывает «моментальный снимок», а не фактические данные. Из документов http://dev.mysql.com/doc/refman/5.0/en/set-transaction.html#isolevel_repeatableread: «Все согласованные чтения в одной транзакции считывают моментальный снимок, установленный первым чтением». –

+1

@Derek Litz Я прав, что вы говорите: данные CAN/MAY могут быть изменены с третьей стороны, в то время как транзакция происходит, но чтение все равно будет видеть «старые» исходные данные, как если бы это изменение не было (моментальный снимок). – Programster

48

Многократное чтение

состояние базы данных сохраняется с начала транзакции. Если вы получите значение в session1, то обновите это значение в session2, получив его снова в session1, вернет те же результаты. Считывание повторяемо.

session1> BEGIN; 
session1> SELECT firstname FROM names WHERE id = 7; 
Aaron 

session2> BEGIN; 
session2> SELECT firstname FROM names WHERE id = 7; 
Aaron 
session2> UPDATE names SET firstname = 'Bob' WHERE id = 7; 
session2> SELECT firstname FROM names WHERE id = 7; 
Bob 
session2> COMMIT; 

session1> SELECT firstname FROM names WHERE id = 7; 
Aaron 

Read Совершенные

В контексте транзакции, вы всегда будете получать самое последнее зафиксированное значение. Если вы получите значение в session1, обновите его в session2, а затем извлеките его в session1again, вы получите значение, измененное в session2. Он читает последнюю зафиксированную строку.

session1> BEGIN; 
session1> SELECT firstname FROM names WHERE id = 7; 
Aaron 

session2> BEGIN; 
session2> SELECT firstname FROM names WHERE id = 7; 
Aaron 
session2> UPDATE names SET firstname = 'Bob' WHERE id = 7; 
session2> SELECT firstname FROM names WHERE id = 7; 
Bob 
session2> COMMIT; 

session1> SELECT firstname FROM names WHERE id = 7; 
Bob 

Имеет смысл?

+0

Я попробовал Повторяемый Чтение в SQL Server 2008 с «заданием уровня повторяемости чтения». Создано два окна запросов sql. Но не получилось. Зачем? –

+1

Почему вторая сессия1 все еще читала Аарона? Разве транзакция Session2 не завершена и не завершена? Я знаю это старое, но, может быть, кто-то может пролить свет. –

+5

Я думаю, что повторное чтение блокирует второй сеанс до первого сеанса. Так что пример неверен. – Nighon

9

Старый вопрос, который уже принят, но мне нравится думать об этих двух уровнях изоляции с точки зрения того, как они меняют поведение блокировки в SQL Server. Это может быть полезно для тех, кто отлаживает тупики, как я.

READ COMMITTED (по умолчанию)

Общие замки принимаются в SELECT, а затем выпустили когда ЗЕЬЕСТ завершает. Таким образом система может гарантировать, что нет грязных чтений незафиксированных данных. Другие транзакции могут по-прежнему изменять базовые строки после завершения выполнения SELECT и до завершения транзакции.

REPEATABLE READ

Общие замки принимаются в SELECT, а затем выпустили только после завершения транзакции. Таким образом система может гарантировать, что прочитанные вами значения не изменятся во время транзакции (поскольку они остаются заблокированными до завершения транзакции).

-1

Мое наблюдение за первоначальным принятым решением.

Под RR (по умолчанию mysql) - Если tx открыт и вызывается SELECT, другой tx НЕ может удалить любую строку, принадлежащую предыдущему набору результатов READ, до тех пор, пока не будет зафиксирован предыдущий tx (фактически оператор delete в новом tx будет просто зависать), однако следующий tx может удалить все строки из таблицы без проблем. Btw, следующий READ в предыдущем tx будет по-прежнему видеть старые данные до тех пор, пока они не будут зафиксированы.

+2

Возможно, вы захотите поместить его в раздел комментариев для ответчика, чтобы получить уведомление. Таким образом, он сможет ответить на ваши замечания и внести исправления, если это необходимо. – RBT

9

Просто ответ по моему чтению и пониманию к этой теме и @ Рем-Ruşanu ответу основан на этом простом сценарии:

Есть два процесса А и В. Процесса B читает таблицу X процесса A записывается в таблицу X Процесс B снова читает таблицу X.

  • ReadUncommitted: Процесс B может считывать незафиксированные данные из процесса А и он может видеть различные строки на основе B письменной форме. Нет блокировки вообще
  • ReadCommitted: Процесс B может читать ТОЛЬКО зафиксированные данные из процесса A, и он может видеть разные строки на основе COMMITTED только B записи. можно ли назвать это простой замок?
  • RepeatableRead: Процесс B будет считывать те же данные (строки), которые выполняются процессом A. Но процесс A может изменить другие строки. Блок уровней
  • Сериализуемый: Процесс B будет читать те же строки, что и раньше, и процесс A не может читать или писать в таблице. Блок на уровне стола
  • Снимок: у каждого процесса есть своя копия, и они работают над ней. У каждого есть свой вид
0

Попытка объяснить это сомнение простой схемой.

Чтения Совершенное: Здесь, в этом уровне изоляции, Транзакция T1 будет чтение обновленного значения X совершенных транзакций T2.

Read Committed

Повторяется Read: На этом уровне изоляции, сделка T1 не будет рассматривать изменения, совершенные транзакции Т2.

enter image description here