Будет ли UPDLOCK в Microsoft SQL Server предотвращать вставку ключей в запросе IF EXISTS? - PullRequest
0 голосов
/ 27 апреля 2018

У меня есть таблица, похожая на эту ...

CREATE TABLE [Customer]
(
    [Id] BIGINT IDENTITY NOT NULL,
    [AccountName] CHARACTER VARYING(255),

    CONSTRAINT [PK_Customer_Id] PRIMARY KEY ([Id]),
    CONSTRAINT [UQ_Customer_AccountName] UNIQUE ([AccountName])
)

Я хочу выполнить этот запрос одновременно из многих приложений ...

IF NOT EXISTS(SELECT [AccountName] FROM [Customers] WITH (UPDLOCK, HOLDLOCK) WHERE [AccountName] = 'SuperCustomer') THEN
BEGIN
    INSERT INTO [Customers] ([AccountName]) VALUES ('SuperCustomer');
END

Может ли WITH (UPDLOCK, HOLDLOCK) предотвратить одновременное выполнение этого запроса от попытки вставки с тем же значением AccountName, даже если строка еще не существует , удерживая блокировку обновления для индекса несуществующих данных ? Я хочу избежать завершения из-за уникального нарушения ограничения на AccountName в таблице Customer в всех случаях, если пользователь пытается отправить одного и того же клиента для создания дважды в одно и то же время или в большом объеме злонамеренно по любой причине. Мы работаем с SET XACT_ABORT ON, и это будет внутри транзакции, которая находится на уровне изоляции READ COMMITTED.

Ответы [ 2 ]

0 голосов
/ 29 апреля 2018

Выбор не находится в транзакции, поэтому я думаю, что он будет освобожден.

IF NOT EXISTS( SELECT [AccountName] 
               FROM [Customers] WITH (UPDLOCK, HOLDLOCK) 
               WHERE [AccountName] = 'SuperCustomer' ) 
THEN
BEGIN
    INSERT INTO [Customers] ([AccountName]) VALUES ('SuperCustomer');
END

Это отдельный оператор, поэтому это транзакция

insert into INSERT INTO [Customers] ([AccountName]) 
select 'SuperCustomer' 
where not exists ( select 1 
                   from [Customers] with (UPDLOCK)
                   where [AccountName] = 'SuperCustomer' )
0 голосов
/ 29 апреля 2018

Проверка этого с использованием двух соединений, с WAITFOR DELAY перед INSERT, показывает, что это эффективный метод. Подсказка HOLDLOCK сохраняет блокировки до конца транзакции (UPDLOCK получает блокировку U для ресурса KEY, который несовместим с другой подобной блокировкой).

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