Зачем блокировать запрос, если не сняты блокировки? - PullRequest
0 голосов
/ 29 ноября 2011

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

Я снова включаю этот запрос, когда уезжаю на день, и прихожу сегодня утром, чтобы увидеть электронные письма, которые начали блокироваться через 5 минут после моего отъезда.

sp_who2 показывает, что мой процесс в настоящее время находится в команде 'WAITFOR', и мой вывод запроса показывает то же самое. В это время не было никаких замков. Но он все еще блокировал другие процессы.

Зачем блокировать процесс, если не было снято никаких блокировок, и почему он блокируется, если не выполняется вставка? WAITFOR находится на вершине цикла while. Снова, я управлял этим весь день без проблем. Он подождал, пока процесс завершится, как должен, и продолжил.

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
go

declare @start bigint
declare @end bigint
declare @max bigint
declare @step int

set @step = 49999
set @start = 120790808
set @end = @start + @step
set @max = @start + 50000000

while ( @end < @max )
begin

while (select COUNT(*) from SomeOtherTable (nolock)) > 0
begin
    print 'Waiting for process'
    waitfor delay '00:00:30'
end

begin transaction

update [TableA] with (tablock)
set [TableA].[ColumnA] = [TableB].[ColumnA]
from [TableB] (nolock)
where [TableB].[ColumnB] = [TableA].[ColumnB]
and [TableA].ID >= @start 
and [TableA].ID <  @end

commit transaction

print @end

if @end >= @max 
begin
    break
end

set @start = @end
set @end = @end + @step

end

Ответы [ 2 ]

0 голосов
/ 29 ноября 2011

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

Если BEGIN TRAN выполняется, но вы никогда не COMMIT или ROLLBACK, транзакция будет оставаться открытой неограниченно долго, что может вызвать все виды трудно отслеживаемых проблем блокировки.

0 голосов
/ 29 ноября 2011

Да, как сказал @ILovePaperTowels - update [TableA] with (tablock) означает блокировку уровня таблицы.он отменяет ваш уровень изоляции

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...