READPAST lock issues with new connection

10,391

Solution 1

This should solve your problem

ALTER PROCEDURE [dbo].[ProcName](@filter bigint, @n int)
AS
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
DELETE FROM TableName WITH (READPAST, UPDLOCK, ROWLOCK) OUTPUT(DELETED.ColumnName2)
WHERE TableName.ID in (select top (@n) ID from TableName where TableName.ColumnName1 = @filter)

Since you are using READPAST, which requires this setting, you might as well set it explicitly in the SP, given that it is safely scoped.

If you issue SET TRANSACTION ISOLATION LEVEL in a stored procedure or trigger, when the object returns control the isolation level is reset to the level in effect when the object was invoked.

Reference: SET TRANSACTION ISOLATION LEVEL

As for why it is happening, a likely reason is connection pooling and mixed transaction isolation levels between SQL calls.

Solution 2

First of all, the DELETE is incorrect. To achieve what you want you need to write it like this:

WITH T AS (
   SELECT TOP (@n)
    ColumnName2
   FROM TableName WITH (READPAST, UPDLOCK, ROWLOCK) 
   WHERE ColumnName1 = @filter)
DELETE FROM T
OUTPUT DELETED.ColumnName2;

This rewrite eliminates the race conditions you have between the UPDATE and the scan for top IDs. In order to work, the WHERE clause must be SARGable (ie. ColumnName1 must be index) otherwise you end up with a scan anyway and the READPAST helps nothing. See Using Tables as Queues for more details.

Now back to your question: what causes a different isolation level? Well, is something in your code which you did not post here. If I'd venture a shot, it must be a TransactionScope object constructed with the default constructor. See Using new TransactionScope() Considered Harmful for a discussion how this happens and why is bad. The article linked contains also the solution: use the explicit constructor of the transaction scope, one that accept a TransactionOptions on which you specify the desired isolation level explicitly.

Share:
10,391
Lajos Arpad
Author by

Lajos Arpad

I was very much interested how computer games work as a kid. I have seen that game graphics are displayed and the logic of the game works well, yet, I knew that this was physically manifested as cables. I decided to become a programmer, since I wanted to know what was behind the wonder that based on cables and electricity a virtual reality is created. Also, I realized that I should not choose another profession, since my handwriting is unreadable. As a kid, nobody took me seriously and when I had a question about programming, I had to go to the library to find the right chapter in the right book. Today, this has become simpler and I am happy to contribute to helping other fellow programmers. In the spirit of Knuth, I consider programming an art and I improve my source-code until I no longer see the difference between profession and art.

Updated on June 04, 2022

Comments