Когда/какие блокировки удерживаются/освобождаются при уровне изоляции READ COMMITTED
Я пытаюсь понять изоляцию/блокировки в SQL Server.
У меня есть следующий сценарий в уровне изоляции READ COMMITTED (по умолчанию)
У нас есть таблица.
create table Transactions(Tid int,amt int)
with some records
insert into Transactions values(1, 100)
insert into Transactions values(2, -50)
insert into Transactions values(3, 100)
insert into Transactions values(4, -100)
insert into Transactions values(5, 200)
Теперь из msdn я понял
Когда выбрано выделение совместная блокировка, поэтому никакая другая транзакция не может изменять данные (избегая грязного чтения). В документации также говорится о уровне строки, уровне страницы, блокировке на уровне таблицы. Я думал о следующем сценарии
Begin Transaction
select * from Transactions
/*
some buisness logic which takes 5 minutes
*/
Commit
То, что я хочу понять, - это то, для какой продолжительности времени будет использоваться общая блокировка, а какая (строка, страница, таблица).
Заблокировать будет только при выполнении оператора select * from Transactions
или он будет приобретаться целых 5+ минут, пока мы не достигнем COMMIT.
Ответы
Ответ 1
блокировка будет выполняться только при запуске select * from Transaction
Вы можете проверить это с помощью кода ниже
откройте сеанс sql и запустите этот запрос
Begin Transaction
select * from Transactions
WAITFOR DELAY '00:05'
/*
some buisness logic which takes 5 minutes
*/
Commit
Откройте еще один сеанс sql и запустите запрос
Begin Transaction
Update Transactions
Set = ...
where ....
commit
Ответ 2
Вы задаете неправильный вопрос, вы обеспокоены деталями реализации. То, о чем вы должны думать и быть заинтересованными, - это семантика уровня изоляции. Kendra Little имеет красивый плакат, объясняющий их: Бесплатный плакат! Руководство по уровня изоляции SQL Server.
Ваш вопрос должен быть перефразирован как:
выберите * из элементов
Q: Какие предметы я увижу?
A: Все совершенные элементы
В: Что произойдет, если есть незафиксированные транзакции, в которые вставлены/удалены/обновлены элементы?
A: ваш SELECT будет заблокирован до тех пор, пока все незафиксированные элементы не будут совершены (или откат).
В: Что произойдет, если новые элементы будут вставлены/удалены/обновлены во время выполнения запроса выше?
A: Результаты не определены. Вы можете увидеть некоторые изменения, не увидите какой-либо другой и возможный блок, пока некоторые из них не совершают.
READ COMMITTED не дает никаких обещаний после завершения вашего заявления, не относящегося к длительности транзакции. Если вы снова запустите инструкцию, у вас снова будет та же семантика, что и раньше, и элементы, которые вы видели ранее, могут меняться, исчезать и появляться новые. Очевидно, это подразумевает, что изменения могут быть внесены в Элементы после выбора.
Более высокие уровни изоляции дают более надежные гарантии: REPEATABLE READ гарантирует, что ни один элемент, который вы выбрали в первый раз, не может быть изменен или удален до фиксации. SERIALIZABLE добавляет гарантию, что ни один новый элемент не может появиться во втором выборе перед фиксацией.
Это то, что вам нужно понять, как работает механизм реализации. После того, как вы освоите эти понятия, вы можете задать детали реализации. Все они описаны в Обработка транзакций: концепции и методы.
Ответ 3
Ваш вопрос хороший. Понимание того, какие блокировки были приобретены, позволяет глубже понять СУБД. В SQL Server под всеми уровнями изоляции (Read Uncommitted, Read Committed (по умолчанию), Повторяемые чтения, Serializable) Исключительные блокировки приобретаются для операций записи.
Исключительные блокировки освобождаются при завершении транзакции, независимо от уровня изоляции.
Разница между уровнями изоляции относится к способу получения/освобождения Shared (Read) Locks.
В разделе Read Uncommitted уровень изоляции, никаких общих блокировок не получено. Под этим уровнем изоляции проблема concurrency известна как "Dirty Reads" (транзакции разрешено считывать данные из строки, которая была изменена другой запущенной транзакцией и еще не выполнена, поэтому ее можно было отбросить) может произойти.
В режиме Read Committed изоляции Shared Locks приобретаются для соответствующих записей. Общие блокировки освобождаются при завершении текущей инструкции. Этот уровень изоляции предотвращает "Dirty Reads" , но, поскольку запись может быть обновлена другими параллельными транзакциями, "Non-Repeatable Reads" (транзакция A извлекает строку, транзакция B впоследствии обновляет строку и транзакцию. Впоследствии она снова возвращает ту же строку Транзакция А извлекает одну и ту же строку дважды, но видит разные данные) или "Phantom Считывает" (в ходе транзакции выполняются два идентичных запроса, а коллекция строк, возвращаемых вторым запросом, отличается от первой) может произойти.
При уровне изоляции повторяющихся чтений, для продолжительности транзакции будут получены Shared Locks. "Dirty Reads" и "Non-Repeatable Reads" предотвращаются, но "Phantom Reads" все еще может произойти.
В соответствии с уровнем изоляции Serializable, для длительности транзакции будут использоваться Shared Locks. Ни одна из вышеупомянутых проблем concurrency не возникает, но производительность резко снижается и возникает риск возникновения Deadlock.