简体   繁体   English

当UPDLOCK在SQL Server中发布时?

[英]When UPDLOCK get released in SQL server?

Recently I have gone through with Hints and Locks in SQL server. 最近,我已经完成了SQL Server中的提示和锁定。 While google about this topic I have read one blog where some query have been written which I am not bale to understand. 在google上有关此主题的信息时,我读了一个博客,其中写了一些我不太理解的查询。 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. BOL状态:读取表时使用更新锁而不是共享锁,并保持锁直到语句或事务结束。 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? 这是否意味着除非执行了事务中的SELECT语句,否则在执行SELECT语句后释放更新锁?

I other words, are my assumptions in the following 2 scenario's correct? 换句话说,在以下两种情况下我的假设正确吗?

Scenario 1: no transaction 方案1:无交易

SELECT something FROM table WITH (UPDLOCK)

/* update locks released */

Scenario 2: with transaction 方案2:进行交易

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) 方案2的示例(stackoverflow博客参考)

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? 我的第二个问题是:一旦同时执行了UPDLOCK的select语句执行完毕,是否释放?

Your assumption in scenario 2 is correct. 您在场景2中的假设是正确的。

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). Update锁将保留在选定的行上,直到事务结束,或者直到update语句修改这些行时转换为互斥锁为止。 Step through each statement one at a time using SSMS to verify. 使用SSMS一次验证一个语句。

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. 至于场景1的情况,所有T-SQL语句都以隐式或显式事务形式存在。 Senario 1 is implicitly: Senario 1是隐式的:

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.

Does this mean that the update locks are released after the execution of the SELECT statement, unless the SELECT statement in within a transaction? 这是否意味着除非执行了事务中的SELECT语句,否则在执行SELECT语句后释放更新锁?

The locks will be released as soon as the row is read..but the lock hold will be U lock,so any parallel transaction trying to modify this will have to wait 读取行后将立即释放锁。但是锁保持将为U锁,因此任何尝试修改此锁的并行事务都必须等待

if you wrap above select in a transaction,locks will be released only when the transaction is committed,so any parallel transaction acquiring locks incompatible with U lock will have to wait 如果在事务中在select之上包装,则仅在提交事务后才会释放锁,因此任何与U锁不兼容的并行事务获取锁都必须等待

begin tran
select * from t1 with (updlock)

for the below second scenario 对于下面的第二种情况

BEGIN TRANSACTION 
SELECT something FROM table WITH (UPDLOCK)

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

Imagine, if your select query returned 100 rows,all will use U lock and imagine the update in same transaction affects 2 rows,the two rows will be converted to x locks .so now your query will have 98 u locks and 2 x locks until the transaction is committed 想象一下,如果您选择的查询返回了100行,那么所有查询都将使用U锁,并且假设同一事务中的更新会影响2行,那么这两行将转换为x锁。因此,现在您的查询将具有98 u锁和2 x锁,直到交易已提交

I would like to think Updlock as repeatable read,any new rows can be added,but any parallel transaction can't delete or update existing rows 我想将Updlock视为可重复读取,可以添加任何新行,但是任何并行事务都不能删除或更新现有行

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM