Я поддерживаю устаревший код с устаревшей базой данных.
Учитывая эту таблицу базы данных
CREATE TABLE Transactions
(
id INT IDENTITY(1,1) NOT NULL,
personId INT NOT NULL,
visitNumber INT NOT NULL
)
, если я хочу, чтобы visitNumber
был уникальным в пределах personId
, вызывает ли следующая вставка условие гонки из-за вызова MAX
?
insert into Transactions (personId, visitNumber)
values (1,
(select isnull(max(visitNumber), 0) + 1
from Transactions
where personId = 1))
Возможно ли, что два запроса могут запускаться одновременно, оба вызывают MAX
одновременно и получают одно и то же значение, а затем оба пытаются вставить одно и то же значение?
Я работаю с существующей базой данных и таблицей, которая работает в течение многих лет. Да, я знаю, что могу добавить уникальный индекс на personId + visitNumber
. Нет, я не могу кардинально изменить дизайн таблицы.
Так, например, у меня может быть две записи с разными значениями personId
и одинаковым значением visitNumber
, но две записи с одинаковым значением personId
могут 'у меня не может быть такого же visitNumber
.
Я думаю, что это не будет иметь условия гонки:
BEGIN TRANSACTION
DECLARE @nextId INT;
SELECT @nextId = ISNULL(MAX(field1), 0) + 1
FROM Transactions WITH (UPDLOCK, HOLDLOCK)
WHERE personId = 1;
INSERT INTO Transactions (personId, visitNumber)
VALUES (1, @nextId)
COMMIT TRANSACTION