когда / какие блокировки удерживаются / снимаются на уровне изоляции 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 я понял

При срабатывании select выполняется общая блокировка, поэтому никакая другая транзакция не может изменять данные (избегая грязного чтения). В документации также говорится об уровне строки, уровне страницы, блокировке на уровне таблицы. Я думал о следующем сценарии

Begin Transaction

select * from Transactions

/*
some buisness logic which takes 5 minutes

*/

Commit

Я хочу понять, на какой период времени будет получена общая блокировка и на какой (строка, страница, таблица).

Будет ли блокировка сработана только тогда, когда будет запущен оператор select * from Transactions, или она будет срабатывать в течение целых 5+ минут, пока мы не дойдем до COMMIT.


person Pritesh    schedule 04.07.2012    source источник


Ответы (4)


блокировка будет получена только при запуске 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
person Asif    schedule 04.07.2012
comment
Я пробовал, и оператор обновления был завершен, а транзакция чтения была отложена. Вероятно, все разрешено MVCC без какой-либо блокировки при чтении. Кстати, мой READ_COMMITTED_SNAPSHOT установлен в OFF. Возможно, общая блокировка предназначена только для блокировок записи, но все же она позволяет читать. - person Andriy; 21.11.2020

Вы задаете неправильный вопрос, вас беспокоят детали реализации. Вам следует подумать и позаботиться о семантике уровня изоляции. У Кендры Литтл есть красивый плакат, объясняющий их: Бесплатный плакат! Руководство по уровням изоляции SQL Server.

Ваш вопрос следует перефразировать так:

выберите * из пунктов

В: Какие элементы я увижу?
A: Все зафиксированные элементы

Q: Что произойдет, если есть незафиксированные транзакции, которые вставили / удалили / обновили элементы?
A: ваш SELECT будет блокироваться до тех пор, пока все незафиксированные элементы не будут зафиксированы (или откатятся).

В: Что произойдет, если новые элементы будут вставлены / удалены / обновлены при выполнении вышеуказанного запроса?
A: Результаты не определены. Вы можете увидеть некоторые изменения, не увидеть других и заблокировать до тех пор, пока некоторые из них не будут зафиксированы.

READ COMMITTED не дает никаких обещаний после завершения вашего оператора, независимо от длины транзакции. Если вы снова запустите оператор, у вас снова будет точно такая же семантика, что и в предыдущем состоянии, и элементы, которые вы видели раньше, могут измениться, исчезнуть и появиться новые. Очевидно, это означает, что изменения могут быть внесены в элементы после вашего выбора.

Более высокие уровни изоляции дают более надежные гарантии: REPEATABLE READ гарантирует, что ни один элемент, который вы выбрали в первый раз, не может быть изменен или удален, пока вы не зафиксируете его. SERIALIZABLE добавляет гарантию, что ни один новый элемент не может появиться при втором выборе перед фиксацией.

Это то, что вам нужно понять, а не то, как работает механизм реализации. После того, как вы освоите эти концепции, вы можете спросить детали реализации. Все они описаны в Обработка транзакций: концепции и методы.

person Remus Rusanu    schedule 04.07.2012
comment
детали реализации важны, когда вы получаете блокировки таблиц вместо блокировок строк. - person matao; 09.03.2016

Ваш вопрос хороший. Понимание того, какие блокировки используются, позволяет глубже понять СУБД. В SQL Server на всех уровнях изоляции (чтение незафиксировано, зафиксировано чтение (по умолчанию), повторяющееся чтение, сериализуемый) для операций записи устанавливаются монопольные блокировки.

Эксклюзивные блокировки снимаются при завершении транзакции, независимо от уровня изоляции.

Разница между уровнями изоляции относится к способу получения / снятия общих (считываемых) блокировок.

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

На уровне изоляции Read Committed для соответствующих записей устанавливаются общие блокировки. Совместные блокировки снимаются, когда текущая инструкция заканчивается. Этот уровень изоляции предотвращает «грязные чтения», но, поскольку запись может быть обновлена ​​другими параллельными транзакциями, «неповторяющиеся чтения» (транзакция A извлекает строку, транзакция B впоследствии обновляет строку, а транзакция A позже извлекает ту же строку снова. . Транзакция A извлекает одну и ту же строку дважды, но видит разные данные) или может произойти «фантомное чтение» (в ходе транзакции выполняются два идентичных запроса, и набор строк, возвращаемых вторым запросом, отличается от первого). .

На уровне изоляции Repeatable Reads общие блокировки устанавливаются на время транзакции. «Грязные чтения» и «неповторяющиеся чтения» предотвращаются, но «фантомные чтения» все еще могут происходить.

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

person Lucian Bredean    schedule 31.05.2016

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

select * from Transactions
update Transactions set amt = xxx where Tid = xxx

Когда / какие блокировки удерживаются / снимаются на уровне изоляции READ COMMITTED? когда select * from Transactions запущен, блокировка не выполняется.

После update Transactions set amt = xxx where Tid = xxx будет добавлена ​​блокировка X для обновления / обновления ключей, блокировка IX для страницы / вкладки

Все блокировки будут сняты только после фиксации / отката. Это означает, что при работе трансмиссии блокировка не сработает.

person Lei Chi    schedule 17.08.2018