It appears using either HOLDLOCK or UPDLOCK in a transaction (say T1), will not block read access from another transaction (say T2).
As I u
I believe Martin already explained how the updlock can result in an exclusive lock (+1)... and I would rather post this as a comment / question, but my comment is too large...
Here's a quick example of the updlock resulting in the x lock...
IF (OBJECT_ID('tblTest') IS NOT NULL)
DROP TABLE tblTest
CREATE TABLE tblTest (
ID INT NOT NULL
)
BEGIN TRANSACTION
SELECT * FROM dbo.tblTest WITH (UPDLOCK, HOLDLOCK) WHERE ID = 1
SELECT * FROM sys.dm_tran_locks WHERE request_session_id = @@SPID
COMMIT
However, if you add a clustered index to your table, the exclusive table lock goes away, and is replaced with a RangeS-U lock...
ALTER TABLE dbo.tblTest
ADD CONSTRAINT PK_tblTest
PRIMARY KEY CLUSTERED (ID)
BEGIN TRANSACTION
SELECT * FROM dbo.tblTest WITH (UPDLOCK, HOLDLOCK) WHERE ID = 1
SELECT * FROM sys.dm_tran_locks WHERE request_session_id = @@SPID
COMMIT
So basically, do you have a clustered index on this table?
EDIT:
Another example using a non-clustered index...
IF (OBJECT_ID('tblTest') IS NOT NULL)
DROP TABLE tblTest
CREATE TABLE tblTest (
ID INT NOT NULL
)
CREATE NONCLUSTERED INDEX
IX_tblTest ON dbo.tblTest (ID)
BEGIN TRANSACTION
SELECT * FROM dbo.tblTest WITH (HOLDLOCK) WHERE ID = 1
SELECT * FROM sys.dm_tran_locks WHERE request_session_id = @@SPID
COMMIT
Will result in a RangeS-S lock...
But...
BEGIN TRANSACTION
SELECT * FROM dbo.tblTest WITH (UPDLOCK, HOLDLOCK) WHERE ID = 1
SELECT * FROM sys.dm_tran_locks WHERE request_session_id = @@SPID
COMMIT
Will result in an exclusive table lock...