Search code examples
sql-servertransactionslockingdatabase-administrationquery-hints

When UPDLOCK get released in SQL server?


Recently I have gone through with Hints and Locks in SQL server. While googling about this topic I have read one blog where some query have been written which I am not able to understand. Here it is

BOL states: Use update locks instead of shared locks while reading a table, and hold locks until the end of the statement or transaction. I have some trouble translating this. Does this mean that the update locks are released after the execution of the SELECT statement, unless the SELECT statement in within a transaction?

In other words, are my assumptions in the following 2 scenarios correct?

Scenario 1: no transaction

SELECT something FROM table WITH (UPDLOCK)

/* update locks released */

Scenario 2: with transaction

BEGIN TRANSACTION 
SELECT something FROM table WITH (UPDLOCK)

/* some code, including an UPDATE */
COMMIT TRANSACTION

/* update locks released */

Example for scenario 2 (referred for stackoverflow blog)

BEGIN TRAN

SELECT Id FROM Table1 WITH (UPDLOCK)
WHERE AlertDate IS NULL;

UPDATE Table1 SET AlertDate = getutcdate() 
WHERE AlertDate IS NULL;

COMMIT TRAN 

Please help to understand the above query.

My second question is: once execution of select statement completed at same time UPDLOCK get released or not?


Solution

  • Your assumption in scenario 2 is correct.

    To answer your second question, no. The Update locks are held on the selected row(s) until the transaction ends, or until converted to exclusive locks when the update statement modifies those row(s). Step through each statement one at a time using SSMS to verify.

    BEGIN TRAN
        -- execute sp_lock in second session - no locks yet
        SELECT Id FROM Table1 WITH (UPDLOCK) WHERE AlertDate IS NULL;
        -- execute sp_lock in second session - update locks present
        UPDATE Table1 SET AlertDate = getutcdate() WHERE AlertDate IS NULL;
        -- execute sp_lock in second session - update (U) locks are replace by exclusive locks (X) for all row(s) returned by SELECT and modified by the UPDATE (Lock Conversion).
        -- Update locks (U) continue to be held for any row(s) returned by the SELECT but not modified by the UPDATE
        -- exclusive locks (X) are also held on all rows not returned by SELECT but modified by UPDATE. Internally, lock conversion still occurs, because UPDATE statements must read and write.
    COMMIT TRAN 
    
        -- sp_lock in second session - all locks gone.
    

    As for what is going on in scenario 1, all T-SQL statements exist either in an implicit or explicit transaction. Senario 1 is implicitly:

    BEGIN TRAN
         SELECT something FROM table WITH (UPDLOCK)
         -- execute sp_lock in second session - update locks (U) will be present
         COMMIT TRAN;
         -- execute sp_lock in second session - update locks are gone.