3

I have the following T-SQL code:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION T1_Test

    /*This is a dummy table used for "locking" 
    and it doesn't contain any meaningful data.*/        
    UPDATE lockTable 
        SET ID = 1    
        WHERE ID = 1

    DECLARE @Count TINYINT 

    SELECT @Count = COUNT(*)
    FROM debugSP 

    WAITFOR DELAY '00:00:5';

    INSERT INTO debugSP 
        (DateCreated, ClientId, Result)
    SELECT 
        GETDATE(), @@SPID, @Count

COMMIT TRANSACTION T1_Test

I am using "locking" hack marked with comment to acquire the exclusive lock.

NOTE: using TABLOCKX or UPDLOCK hints will not work because I have broken ATOMIC-ity by splitting statements and adding WAITFOR command in the middle for testing purposes. I don't want something like that:

INSERT INTO debugSP (DateCreated, ClientId, Result)
SELECT GETDATE(), @@SPID, COUNT(*) 
FROM debugSP

This is the correct result after running two simultaneous sessions (with lock table)

Id DateCreated           ClientId Result
-- ----------------------- -------- ------
 1 2011-03-17 15:52:12.287       66      0
 2 2011-03-17 15:52:24.534       68      1

and that is the incorrect result of running the code with lock commented out

Id DateCreated           ClientId Result
-- ----------------------- -------- ------
 1 2011-03-17 15:52:43.128       66      0
 2 2011-03-17 15:52:46.341       68      0

Is there a better way of acquiring transaction-wide exclusive lock without such hacks?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Novitzky
  • 4,756
  • 3
  • 23
  • 27
  • 1
    Not exactly sure what you are trying to do. Is this what you need? http://www.sqlteam.com/article/application-locks-or-mutexes-in-sql-server-2005 – Martin Smith Mar 17 '11 at 16:28

2 Answers2

7

I'm not exactly sure what you are trying to do from the posted code. I presume you are just trying to serialize access to that piece of code? If so sp_getapplock should do what you need instead of creating a new dummy table that you just use to take locks on.

Details here

Martin Smith
  • 438,706
  • 87
  • 741
  • 845
1

You can use the locking hint WITH(XLOCK, ROWLOCK) within the scope of a transaction with Repeatable Read isolation. At Serializable isolation the exclusive lock is obtained by default on a read operation, so if you needed a particular transaction to play nice in parallel, you could specify an increased serialization level for that one transaction when creating it (which you are doing; this isn't a hack, just the way things are done depending on the situation).

KeithS
  • 70,210
  • 21
  • 112
  • 164