Если вы не хотите справиться с конфликтом путем создания взаимоблокировок, не используйте SERIALIZABLE для этого.SERIALIZABLE примет и удержит блокировки Shared (S) в первом запросе, поэтому параллельные транзакции будут одновременно читать строку и входить в тупик, когда они оба пытаются обновить ее.Один будет убит;другой преуспеет, и СЕРИАЛИЗУЕМАЯ семантика будет сохранена.
Вместо этого вы должны установить ограничительную блокировку на целевую строку во время ее чтения.
Например:
BEGIN TRANSACTION
Declare @OwnerField Varchar(20)
SET @OwnerField = SELECT OwnerField
FROM Table with (UPDLOCK,HOLDLOCK)
WHERE RecordID = 2
IF @OwnerField IS NULL -- Can own
BEGIN
UPDATE Table
SET OwnerField = 'John Smith'
WHERE RecordID = 2
END
END TRANSACTION
(UPDLOCK, HOLDLOCK) дает вам тот же диапазон -блокировка защиты уровня изоляции SERIALIZABLE, но использует ограничительную блокировку, поэтому несколько транзакций будут блокироваться в SELECT.Второй считыватель будет блокироваться до тех пор, пока не будет зафиксирован первый, и увидит обновленный столбец OwnerField.