Какой тип блокировки помещен для оператора SELECT в транзакции в SQL Server

Я считаю, что каждый SELECT Оператор SQL Server приведет к установке блокировки Shared или Key. Но поместит ли он тот же тип блокировки, когда он находится в транзакции? Позволят ли общие или ключевые блокировки другим процессам читать те же записи?

Например, у меня есть следующая логика

Begin Trans
-- select data that is needed for the next 2 statements
SELECT * FROM table1 where id = 1000; -- Assuming this returns 10, 20, 30

insert data that was read from the first query
INSERT INTO table2 (a,b,c) VALUES(10, 20, 30);

-- update table 3 with data found in the first query
UPDATE table3
SET d = 10,
   e = 20,
   f = 30;

COMMIT;

На этом этапе мой оператор выбора все еще будет создавать общую блокировку или блокировку ключа или будет повышен до эксклюзивной блокировки? Будет ли другая транзакция читать записи из таблицы1 или все транзакции будут ждать, пока моя транзакция будет зафиксирована, прежде чем другие смогут выбрать из нее?

В приложении это делает так, чтобы переместить оператор выбора за пределы транзакции и просто сохранить вставку / обновление в одной транзакции?

1 ответ

Решение

SELECT всегда будет устанавливать общую блокировку - если вы не используете WITH (NOLOCK) подсказка (тогда замок не будет установлен), используйте READ UNCOMMITTED уровень изоляции транзакции (то же самое), или если вы специально не переопределите его с помощью подсказок запроса, таких как WITH (XLOCK) или же WITH (UPDLOCK),

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

В этом случае, если выбрано всего три строки, эскалация блокировок не произойдет (это происходит только тогда, когда за одну транзакцию получено более 5000 блокировок).

В зависимости от уровня изоляции транзакции эти общие блокировки будут удерживаться разное количество раз. С READ COMMITTED, уровень по умолчанию, блокировки снимаются сразу после прочтения данных, в то время как с REPEATABLE READ или же SERIALIZABLE Уровни блокировки будут удерживаться до тех пор, пока транзакция не будет зафиксирована или откатана.

Другие вопросы по тегам