I have a deadlock problem in SQL Server that I could not solve.
Basically, I have a large number of concurrent connections (from many machines) that perform transactions where they first delete a range of records and then reinsert records within the same range with bulk insertion.
Essentially, a transaction looks like this:
BEGIN TRANSACTION T1 DELETE FROM [TableName] WITH( XLOCK HOLDLOCK ) WHERE [Id] =@Id AND [SubId] =@SubId INSERT BULK [TableName] ( [Id] Int , [SubId] Int , [Text] VarChar(max) COLLATE SQL_Latin1_General_CP1_CI_AS ) WITH(CHECK_CONSTRAINTS, FIRE_TRIGGERS) COMMIT TRANSACTION T1
Bulk insert only inserts elements matching the Id and SubId deletes in the same transaction. In addition, these Id and SubId entries should never overlap.
When I have enough simultaneous transactions of this form, I begin to see a significant number of deadlocks between these statements.
I added XLOCK HOLDLOCK locking hints to try to deal with the problem, but they don't seem to be able to cope.
The canonical deadlock graph for this error shows:
Compound 1:
- Holds RangeX-X in PK_TableName
- Holds page lock on page
- X-page lock request in table
Compound 2:
- Holds page lock on page
- RangeX-X Lock Queries on a Table
What do I need to do to make sure that these deadlocks do not occur.
I read about RangeX-X locks, and I'm not sure I fully understand what happens to them. Do I have any options besides locking the whole table here?
source share