У меня есть две таблицы, подобные этой:
Table1 Table2
----------------------------------
Table1Id IDENTITY Table2Id
Table2Id NOT NULL SomeStuff
SomeOtherStuff
С ограничением внешнего ключа для Table2Id между ними. Само собой разумеется (все же я говорю это в любом случае), что строка Table2 должна быть вставлена перед связанной строкой Table1. Природа процедуры, которая загружает обе таблицы, делает это в массовых операциях с множествами, то есть у меня есть целая куча данных Table1 и Table2 в таблице @temp, которая была создана со столбцом IDENTITY
для отслеживания вещей. В настоящее время я делаю вставки, как это (обработка транзакций и ошибок для краткости опущена):
DECLARE @currentTable2Id INT
SET @currentTable2Id = IDENT_CURRENT('dbo.Table2')
INSERT INTO dbo.Table2 WITH (TABLOCKX)
( SomeStuff,
SomeOtherStuff
)
SELECT WhateverStuff,
WhateverElse
FROM @SomeTempTable
ORDER BY SomeTempTableId
INSERT INTO dbo.Table1
( Table2Id )
SELECT @currentTable2Id + SomeTempTableId
FROM @SomeTempTable
ORDER BY SomeTempTableId
Это прекрасно работает, все отношения являются звуковыми после вставок. Однако из-за TABLOCKX
мы сталкиваемся с постоянными ситуациями, когда люди ждут завершения запросов друг друга, будь то этот запрос «загрузки» или другие ОБНОВЛЕНИЯ и ВСТАВКИ (я использую NOLOCK
для выбора ). Природа проекта требует, чтобы было загружено много данных, поэтому бывают случаи, когда эта процедура может выполняться в течение 20-30 минут. Я ничего не могу с этим поделать. Поверь мне, я пытался.
Я не могу использовать SET IDENTITY_INSERT ON
, поскольку администраторы баз данных не позволяют пользователям вводить эту команду в производственном процессе, и я думаю, что для использования IDENTITY_INSERT
в любом случае потребуется TABLOCKX
. Есть ли способ, которым я могу сделать такую вставку без использования TABLOCKX
?