6 ответов:
Read committed-это уровень изоляции, который гарантирует, что любые данные были прочитаны совершено на данный момент читается. Это просто ограничивает читателя от просмотра любого промежуточного, незафиксированного, "грязного" чтения. Он не дает никаких обещаний, что если транзакция повторно выдает чтение, найдет то же самое данные, данные могут быть изменены после того, как он был прочитан.
Repeatable read-это более высокий уровень изоляции, который в дополнение к гарантиям чтения зафиксированный уровень, он также гарантирует, что любые данные читаются не могу изменить, если транзакция снова считывает те же данные, она найдет ранее считанные данные на месте, без изменений и доступны для чтения.
следующий уровень изоляции, сериализуемый, делает еще более сильную гарантию: в дополнение ко всем повторяемым гарантиям чтения, он также гарантирует, что нет новая данные можно увидеть при последующем чтении.
скажем, у вас есть таблица T со столбцом C с одной строкой в нем, скажем, имеет значение '1'. И рассмотрим у вас есть простая задача, как следующее:
BEGIN TRANSACTION; SELECT * FROM T; WAITFOR DELAY '00:01:00' SELECT * FROM T; COMMIT;это простая задача, которая выдает два чтения из таблицы T, с задержкой в 1 минуту между ними.
- в разделе READ COMITTED второй SELECT может вернуть любой данные. Параллельная транзакция может обновить запись, удалить ее, вставить новые записи. Второй выбор всегда будет видеть новая данные.
- при повторяемом чтении второй SELECT гарантированно увидит строки, которые видели при первом select без изменений. Новые строки могут быть добавлены параллельной транзакцией в течение одной минуты, но существующие строки не могут быть удалены или изменены.
- при СЕРИАЛИЗУЕМЫХ чтениях второй выбор гарантированно увидит ровно те же строки, что и первый. Ни одна строка не может быть изменена, ни удалена, ни новые строки не могут быть вставлены параллельным торговая операция.
Если вы будете следовать логике выше, вы можете быстро понять, что сериализуемые транзакции, хотя они могут облегчить вам жизнь, всегда полностью заблокировав все возможные параллельные операции, так как они требуют, чтобы никто не мог изменить, удалить или вставить любую строку. Уровень изоляции транзакций по умолчанию .Net
System.Transactionsобласть сериализуема, и это обычно объясняет ужасную производительность, которая приводит.и, наконец,, существует также уровень изоляции моментальных снимков. Уровень изоляции моментальных снимков обеспечивает те же гарантии, что и сериализуемость, но не требует, чтобы никакая параллельная транзакция не могла изменять данные. Вместо этого он заставляет каждого читателя видеть свою собственную версию мира (это собственный "снимок"). Это делает его очень легко программировать против, а также очень масштабируемым, поскольку он не блокирует параллельные обновления. Однако это преимущество связано с ценой: дополнительное потребление ресурсов сервера.
дополнительные читает:
Повторимое Чтение
состояние базы данных поддерживается с начала транзакции. Если вы извлекаете значение в 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Читать Committed
в контексте транзакции вы всегда будете получать самое последнее зафиксированное значение. Если вы извлекаете значение в 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смысл?
просто ответ в соответствии с моим чтением и пониманием этой темы и ответ @remus-rusanu основан на этом простом сценарии:
есть два процесса A и B. Процесс B-это чтение таблицы X Процесс A записывается в таблицу X Процесс B снова читает таблицу X.
- ReadUncommitted: процесс B может считывать незафиксированные данные из процесса A, и он может видеть разные строки на основе записи B. отсутствие замка на все
- ReadCommitted: процесс B может читать только зафиксированные данные из процесса A, и он может видеть разные строки на основе зафиксированной только записи B. можно ли назвать это простой замок?
- RepeatableRead: процесс B будет читать те же данные (строки), что и процесс A. Но процесс может изменить другие строки. строк блока
- Serialisable: процесс B будет читать то же самое строки, как и раньше, и процесс A не могут читать или записывать в таблицу. таблицу уровня блока
- снимок: каждый процесс имеет собственную копию и они работают над этим. каждый из них имеет свой собственный вид
старый вопрос, который уже имеет принятый ответ, но мне нравится думать об этих двух уровнях изоляции с точки зрения того, как они изменяют поведение блокировки в SQL Server. Это может быть полезно для тех, кто отлаживают тупики, как я был.
Read COMMITTED (по умолчанию)
общие блокировки берутся в SELECT, а затем освобождаются когда оператор SELECT завершает. Вот как система может гарантировать, что нет грязных чтений из незафиксированных данных. Другие транзакции могут по-прежнему изменять базовые строки после завершения выбора и до завершения транзакции.
ПОВТОРЯЕМОЕ ЧТЕНИЕ
общие блокировки берутся в SELECT, а затем освобождаются только после завершения транзакции. Таким образом, система может гарантировать, что значения, которые Вы читаете, не изменятся во время транзакции (потому что они остаются заблокированными до завершения транзакции).
пытаясь объяснить это сомнение с помощью простых диаграмм.
Читать Committed: здесь на этом уровне изоляции транзакция T1 будет считывать обновленное значение X, зафиксированное транзакцией T2.
Повторимое Чтение: на этом уровне изоляции транзакция T1 не будет учитывать изменения, совершенные транзакцией T2.
мое замечание о начальном принятом решении.
под RR (по умолчанию mysql) - если tx открыт и SELECT был запущен, другой tx не может удалить любую строку, принадлежащую предыдущему набору результатов чтения, пока не будет зафиксирован предыдущий tx (на самом деле оператор delete в новом tx просто зависнет), однако следующий tx может удалить все строки из-за стола без каких-либо проблем. Кстати, следующее чтение в предыдущем tx все равно будет видеть старые данные, пока оно не будет зафиксировано.


Comments