2014-09-10 2 views
1

Как управлять параллелизмом в SQL Server SELECT-запросах?Как управлять параллелизмом в SQL Server SELECT-запросах?

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

Как я мог справиться с этим?

Сессия 1:

BEGIN TRAN 

DECLARE @Id INT 

SELECT TOP 1 @Id = Id 
FROM dbo.Table_1 

UPDATE dbo.Table_1 
SET is_taken = 1 
WHERE Id = @Id 

COMMIT TRAN 

Сессия 2:

BEGIN TRAN 

DECLARE @Id INT 

SELECT TOP 1 @Id = Id 
FROM dbo.Table_1 

UPDATE dbo.Table_1 
SET is_taken = 1 
WHERE Id = @Id 

COMMIT TRAN 
+1

Какая у вас настройка изоляции? –

+3

Что значит, что они не должны брать одну и ту же запись? Вы используете верхнюю 1, но нет порядка, так что нет гарантии, какую строку вы вернете. –

+0

Они никогда не смогут обновить одну и ту же запись - даже если оба они получат одинаковое значение @ @ id. Если # 1 получает блокировку обновления в строке с '@ Id', то # 2 не может запустить обновление - ему придется подождать, пока не будет # 1. –

ответ

0

Как уже упоминалось в комментариях, SQL Server берет на себя изоляцию, следовательно, вы можете просто запустить обновление без выбора:

UPDATE TOP (1) dbo.Table_1 
SET is_taken = 1 

Я предполагаю, что вы имели в виду также есть условие на выбор, чтобы избежать каждый раз обновляя одну и ту же запись:

UPDATE TOP (1) dbo.Table_1 
SET is_taken = 1 
OUTPUT INSERTED.Id into @id 
WHERE is_taken != 1 
+0

Каков наилучший уровень ИЗОЛЯЦИИ для этого? –

+0

READ COMMITTED - это все, что вы ищете – Bulat

0

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

Это должно устранить любые проблемы, с которыми вы сталкиваетесь между сеансом.

Understand Locking in SQL Server

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