Я думаю, что вышеупомянутые уровни изоляции так похожи. Может ли кто-нибудь описать с хорошими примерами, в чем главное отличие?
Я думаю, что вышеупомянутые уровни изоляции так похожи. Может ли кто-нибудь описать с хорошими примерами, в чем главное отличие?
Ответы:
Чтение совершено это уровень изоляции , который гарантирует , что любой Считанные данные были совершены в момент чтения. Это просто ограничивает читателя от просмотра любого промежуточного, незафиксированного, «грязного» чтения. Не дается никаких обещаний, что если транзакция повторно выдаст чтение, найдет те же данные, данные могут свободно изменяться после их чтения.
Повторяемое чтение - это более высокий уровень изоляции, который, в дополнение к гарантиям уровня подтвержденного чтения, также гарантирует, что никакое чтение данных не может измениться , если транзакция снова считывает те же данные, она найдет ранее прочитанные данные на месте, без изменений и доступны для чтения.
Следующий уровень изоляции, сериализуемый, дает еще более сильную гарантию: в дополнение ко всему, что гарантирует повторяемое чтение, он также гарантирует, что никакие новые данные не будут видны при последующем чтении.
Допустим, у вас есть таблица T со столбцом C с одной строкой, скажем, она имеет значение «1». И учтите, что у вас есть простая задача, подобная следующей:
BEGIN TRANSACTION;
SELECT * FROM T;
WAITFOR DELAY '00:01:00'
SELECT * FROM T;
COMMIT;
Это простая задача, которая выдает два чтения из таблицы T с задержкой в 1 минуту между ними.
Если вы будете следовать приведенной выше логике, вы сможете быстро понять, что SERIALIZABLE транзакции, хотя они могут облегчить вам жизнь, всегда полностью блокируют все возможные параллельные операции, поскольку они требуют, чтобы никто не мог изменять, удалять или вставлять какие-либо строки. Уровень изоляции транзакции по умолчанию для области .Net System.Transactions
является сериализуемым, и это обычно объясняет ужасную производительность, которая в результате.
И наконец, есть также уровень изоляции SNAPSHOT. Уровень изоляции SNAPSHOT обеспечивает те же гарантии, что и сериализуемые, но не требует, чтобы никакая параллельная транзакция не могла изменить данные. Вместо этого он заставляет каждого читателя видеть свою собственную версию мира (свой собственный «снимок»). Это позволяет очень легко программировать, а также очень масштабируемо, поскольку не блокирует одновременные обновления. Однако это преимущество имеет цену: дополнительное потребление ресурсов сервера.
Дополнительные чтения:
Состояние базы данных сохраняется с начала транзакции. Если вы извлекаете значение в сеансе 1, то обновляете это значение в сеансе 2, и его повторное получение в сеансе 1 возвращает те же результаты. Чтения повторяются.
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
В контексте транзакции вы всегда получите самое последнее зафиксированное значение. Если вы извлекаете значение в 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.
Старый вопрос, на который уже есть принятый ответ, но мне нравится думать об этих двух уровнях изоляции с точки зрения того, как они изменяют поведение блокировки в SQL Server. Это может быть полезно для тех, кто отлаживает тупики, как я.
READ COMMITTED (по умолчанию)
Совместно используемые блокировки берутся в SELECT, а затем снимаются после завершения оператора SELECT . Таким образом, система может гарантировать отсутствие грязных операций чтения незафиксированных данных. Другие транзакции могут по-прежнему изменять базовые строки после завершения SELECT и до завершения транзакции.
ПОВТОРЯЕМЫЙ ЧИТАТЬ
Общие блокировки принимаются в SELECT, а затем снимаются только после завершения транзакции . Таким образом, система может гарантировать, что прочитанные вами значения не изменятся во время транзакции (поскольку они остаются заблокированными до завершения транзакции).
Попытка объяснить это сомнение с помощью простых диаграмм.
Read Committed: здесь, на этом уровне изоляции, транзакция T1 будет считывать обновленное значение X, зафиксированное транзакцией T2.
Повторяемое чтение: на этом уровне изоляции транзакция T1 не будет учитывать изменения, зафиксированные транзакцией T2.
Я думаю, что эта картина также может быть полезной, она помогает мне в качестве справки, когда я хочу быстро вспомнить различия между уровнями изоляции (благодаря kudvenkat на YouTube)
Обратите внимание, что повторяемое в повторяемом чтении относится к кортежу, но не ко всей таблице. На уровнях изоляции ANSC может возникнуть аномалия фантомного чтения , что означает, что чтение таблицы с одинаковым предложением where дважды может возвращать разные возвращаемые разные наборы результатов. Буквально это не повторяется .
Мое наблюдение за изначально принятым решением.
Под RR (по умолчанию mysql) - если tx открыт и SELECT запущен, другой tx не может удалить ни одну строку, принадлежащую предыдущему набору результатов READ, пока предыдущий tx не будет зафиксирован (фактически, оператор delete в новом tx просто зависнет) Однако следующий tx может удалить все строки из таблицы без каких-либо проблем. Кстати, следующий READ в предыдущем tx будет по-прежнему видеть старые данные, пока не будет зафиксирован.