2009-04-29 2 views
1

Есть ли способ заблокировать SELECT в транзакции? Если выполняется SELECT, больше не выполняется SELECT, пока первый не завершен.SQL Server 2005 - Есть ли способ заблокировать SELECT в транзакции?

Спасибо!

+2

Почему вы хотите это сделать? – tpdi

+0

"заблокировать SELECT в транзакции"? Предполагается ли, что оно обнаружено в транзакции, а не иначе? Или вы имеете в виду «выполнить селеки серийно в транзакции - выполнить одно полностью, прежде чем запускать другое»? Это, я думаю, единственный способ, которым это когда-либо срабатывает. – dkretz

ответ

2

Не уверен, что правильно понял ваш вопрос, но если вы хотите наложить более строгую блокировку, чем по умолчанию SQL Server, вы можете либо повысить уровень изоляции, либо использовать подсказку блокировки. Это может быть полезно, если вам сначала нужно выбрать SELECT, а затем позже, на основе значения SELECT, выполните UPDATE. Чтобы избежать фантомного UPDATE из другой транзакции (в котором значение, выбранное вами ранее SELECTed, было изменено в ч/б SELECT и UPDATE), вы можете наложить блокировку обновления в инструкцию SELECT.

Например:

select * from mytable with (holdlock, xlock) 

Обратите внимание, что ЗЕЬЕСТ выше использует более строгую блокировку обновления & удерживает эту блокировку на время операции. Вы также хотите, чтобы обернуть ваши заявления в явной транзакции, как:

begin transaction 
select * from mytable with (holdlock, xlock) -- exclusive lock held for the entire transaction 
-- more code here... 
update mytable set col='whatever' where ... 
commit transaction 

Будьте осторожны, конечно, для длительных операций.

+0

+1 но: Уточнение не предотвращает выполнение других Selects. Это предотвращает другие обновления, это означает обновление и выбор с помощью updlocks. –

+0

OK, попробуйте что-то вроде этого: выберите * from mytable с (holdlock, xlock) Это, безусловно, блокирует SELECT, происходящие в контексте других подключений. – Garrett

0

Вам нужен уровень изоляции SERIALIZABLE:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE 

Другие SELECT запросы будут блокироваться, пока транзакция не будет завершена в этом случае. Уровень по умолчанию, как правило, READ COMMITTED.

0

похоже, что вы ищете пессимистическую стратегию блокировки, но без фактической блокировки ваших данных. посмотрите на Application locks в sql-сервере.

0

Изменение уровня изоляции обычно является вашим лучшим выбором.

Но, если по какой-либо причине, что это не вариант для вас - вы также можете сделать эксклюзивную блокировку таблицы ...

select * from MyTable with (tablockx) 

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

Смежные вопросы