Устранение проблемы upsert с УЧЕТОМ УРОВНЯ ИЗОЛЯЦИИ СДЕЛКИ, ПОВТОРЯЕМОГО ЧИТАТЬ? - PullRequest
1 голос
/ 19 октября 2011

У меня есть оператор SQL, который выполняет обновление, а затем, если @@ROWCOUNT равен 0, он будет вставлен. это в основном MERGE в SQL 2008. Мы сталкиваемся с ситуациями, когда два потока терпят неудачу при обновлении одновременно Он попытается вставить один и тот же ключ дважды в таблицу. Мы используем уровень изоляции транзакции по умолчанию, Read Committed. Исправит ли это изменение уровня на повторяющиеся чтения или мне придется пройти весь путь до Serializable, чтобы эта работа работала? Вот некоторый код:

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;

BEGIN TRAN;                                            
UPDATE TableA
SET Duration = @duration              
WHERE keyA = @ID
AND keyB = @IDB;

IF @@rowcount = 0
BEGIN

INSERT INTO TableA (keyA,keyB,Duration) 
VALUES (@ID,@IDB,@duration); 

END
COMMIT TRAN;

SET TRANSACTION ISOLATION LEVEL READ COMMITTED;";

1 Ответ

2 голосов
/ 19 октября 2011

Вам нужно будет пройти весь путь до SERIALIZABLE.

В REPEATABLE READ, если строка не существует, тогда оба оператора UPDATE могут выполняться одновременно, не блокируя друг друга, и продолжить выполнение вставки. При SERIALIZABLE диапазон, в котором была бы строка, блокируется.

Но вам также следует рассмотреть возможность оставить уровень изоляции по умолчанию read committed и наложить уникальное ограничение на keyA,keyB, чтобы любые попытки вставить дублирование не дали результата с ошибкой.

...