Quantcast
Channel: SQLServerCentral » SQL Server 2014 » Development - SQL Server 2014 » Latest topics
Viewing all articles
Browse latest Browse all 3145

sys.dm_tran_locks or How to avoid a TRUNCATE TABLE to be blocked

$
0
0
I have a couple of processes that will (re-)populate a table nightly - a simple TRUNCATE TABLE and INSERT INTO / SELECT FROM. There should not be any application activity at this time, but experience shows that occasionally, someone will leave something up that holds a lock. I'd like to "surgically" identify and kill any SPIDs that would cause the TRUNCATE to be blocked.I don't want to affect anything that won't stop the TRUNCATE (and subsequent INSERT INTO) operations, but I do want to make sure the operations succeed. It seems like overkill to kill all SPIDs and set the database in single user mode for this.It seems a very simple approach (not tested at this point) would be to simply look for SPIDs with entries in sys.dm_tran_locks, limiting it to the database (resource_database_id) and table (resource_associated_entity_id) in question, and eliminating the SPID of the process running the KILL.The table(s) in question will have a Primary Key (non-clustered) and a clustered, non-unique index.Do I need to look anywhere else? Do I need to also consider the possibility that an allocation unit, etc. with a resource_associated_entity_id different from the table I'm concerned with? Do I need to restrict to certain types of locks? Other concerns?What happens if the KILL SPID triggers a ROLLBACK? How do I monitor the rollback completion? If the transaction will remain in sys.dm_tran_locks until rollback is completed, is there a value that indicates it so I can implement waits?[code="sql"]IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[KillSPIDsLockingTable]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[KillSPIDsLockingTable]GOCREATE PROCEDURE KillSPIDsLockingTable ( @TableName sysname, @DatabaseName sysname = DB_NAME)ASBEGIN DECLARE @KillSPID INT SELECT TOP 1 @KillSPID = tl.request_session_id FROM sys.dm_tran_locks tl WHERE resource_database_id = DB_ID(@DatabaseName) AND resource_associated_entity_id = OBJECT_ID(@TableName) -- How about Allocation Units, HOBTs, items with other names? AND tl.request_session_id <> @@SPID WHILE @@ROWCOUNT = 1 BEGIN --KILL @KillSPID PRINT @KillSPID -- Just testing ATM SELECT TOP 1 @KillSPID = tl.request_session_id FROM sys.dm_tran_locks tl WHERE resource_database_id = DB_ID(@DatabaseName) AND resource_associated_entity_id = OBJECT_ID(@TableName) -- How about Allocation Units, HOBTs, items with other names? AND tl.request_session_id <> @@SPID -- Exclude processes that are rolling back, possibly from an issued KILL? END -- Wait for ROLLBACKS to complete after spids are killed...?ENDGO--SELECT * FROM dbo.TestData AS tdEXEC KillSPIDsLockingTable @TableName = 'dbo.TestData', @DatabaseName = 'TBTest'[/code]

Viewing all articles
Browse latest Browse all 3145

Trending Articles