I am testing a process that deletes many, many records at once. It cannot TRUNCATE TABLE
, because there are records in there that need to stay.
Because
You or somebody else using the connection is setting the lock timeout to something other than the default. See http://msdn.microsoft.com/en-US/library/ms189470(v=SQL.90).aspx for details.
The default lock time it is -1 milliseconds, meaning "Wait Forever".
The row hints are nice, but they are a code smell and should be avoided. Let SQL Server do its job. It's got more information than you do about the system as a whole.
For starters, you can't control the lock size: Lock escalation occurs automatically, based on the number of outstanding locks. It starts with row locks. If you accumulate too many row locks, SQL Server escalates to page lock. Acquire too many page locks and it escalates to table locks. See http://msdn.microsoft.com/en-us/library/ms184286(v=SQL.90).aspx for lock escalation details. There are a couple of trace flags you can set, however, that will prevent lock escalation: however, that will degrade the SQL Server's performance.
Another thing: you should wrap the DELETE
statement in a transaction, especially in a stored procedure.
DECLARE @Count INT
SET @Count = 1
WHILE @Count > 0
BEGIN
BEGIN TRANSACTION
DELETE TOP (1000) FROM MyTable WITH (ROWLOCK, READPAST) WHERE MyField = SomeValue
SET @Count = @@ROWCOUNT
COMMIT TRANSACTION
END
This makes clear your intent and ensures that locks are release when they ought to be.