I have two tables like this:
Table1 Table2
----------------------------------
Table1Id IDENTITY Table2Id
Table2Id NOT NULL SomeStuff
SomeOtherStuff
With a foreign key constraint on Table2Id between them. It goes without saying (yet I'm saying it anyway) that a Table2 row needs to be inserted before its related Table1 row. The nature of the procedure that loads both tables does so in bulk set operations, meaning I have a whole bunch of Table1 and Table2 data in a @temp table that was created with an IDENTITY
column to keep track of things. I am currently doing the inserts like this (transaction and error handling omitted for brevity):
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
This works fine, all of the relationships are sound after the inserts. However, due to the TABLOCKX
, we are running into constant situations where people are waiting for each other's queries to finish, whether it be this "load" query, or other UPDATES and INSERTS (I'm using NOLOCK
on selects). The nature of the project calls for a lot of data to be loaded, so there are times when this procedure can run for 20-30 minutes. There's nothing I can do about this performance. Trust me, I've tried.
I cannot use SET IDENTITY_INSERT ON
, as the DBAs do not allow users to issue this command in production, and I think using IDENTITY_INSERT
would require a TABLOCKX
anyways. Is there any way I can do this sort of insert without using a TABLOCKX
?