Reputation: 4876
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?
Upvotes: 3
Views: 9737
Reputation: 71573
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).
Upvotes: 1
Reputation: 453278
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.
Upvotes: 7