更新锁用于什么

时间:2014-06-07 07:01:01

标签: sql-server locking deadlock

我正在阅读Understanding Locking in SQL Server。但我不太了解更新锁的目的。

详情说明如下:

  

更新锁

     

更新(U)锁可防止常见形式的死锁。典型的更新模式包括读取记录的事务,获取资源(页面或行)上的共享(S)锁,然后修改行,这需要锁转换为独占(X)锁。如果两个事务获取资源上的共享模式锁,然后尝试同时更新数据,则一个事务会尝试将锁转换为独占(X)锁。共享模式到独占锁定转换必须等待,因为一个事务的独占锁定与另一个事务的共享模式锁定不兼容;锁定等待发生。第二个事务尝试获取其更新的独占(X)锁。因为两个事务都转换为独占(X)锁,并且它们都在等待另一个事务释放其共享模式锁,所以会发生死锁。

     

为避免此潜在的死锁问题,使用更新(U)锁。一次只有一个事务可以获得对资源的更新(U)锁定。如果事务修改资源,则更新(U)锁将转换为独占(X)锁。否则,锁将转换为共享模式锁。

考虑以下两个事务(两个事务都在Isolation Level Repeatable Read执行,以便在事务期间保持S锁定):

在TRAN1中执行以下SQL。

BEGIN TRAN
SELECT BrandName FROM dbo.Brand WHERE BrandId=2

现在,TRAN1为RID授予S锁

在TRAN2中执行以下SQL

 BEGIN TRAN
 SELECT BrandName FROM dbo.Brand WHERE BrandId=2

现在,TRAN2为与TRAN1

相同的RID资源授予S锁

在TRAN1中执行以下SQL

UPDATE dbo.Brand SET BrandName='YBrand' WHERE BrandId=2

现在,TRAN1 S锁定转换为U锁定并且U锁定等待TRAN2 S锁定释放转换为X锁定

在TRAN2中执行以下SQL

UPDATE dbo.Brand SET BrandName='ZBrand' WHERE BrandId=2

然后发生死锁。

向上死锁与U锁用于防止的描述完全相同。但死锁仍然存在。

所以我的问题是:U锁与X锁不同?哪种情况可以防止死锁而不是使用X锁?

2 个答案:

答案 0 :(得分:2)

UPDATE操作分为两步:

  1. 首先使用(U)(更新)锁读取现有值

  2. 然后将该锁转换为独占(X)锁以写回新的(更新的)值。

  3. 由于您的REPEATABLE READ隔离级别,并且因为您已经安排了这样的陈述,是的,您将陷入僵局。但我真的不明白这与update锁定有什么关系......(这真的只是因为你已经安排好这样的代码而且因为你'重新使用REPEATABLE READ)。

    主要"福利" (U)锁的问题是,在那段时间内仍然可以使用其他(S)共享锁。例如。当一个事务使用(U)锁读取要更新的值时,另一个事务可以使用(S)中的SELECT共享锁读取相同的值(如果{您有一个独有的(X)锁定,例如当您执行DELETE

    如果您有两个仅仅UPDATESELECTREPEATABLE READ进行交易的交易 - 那么第一笔交易所采取的(U)锁将阻止第二个事务也来自读取该值(因为(U)锁定不兼容 - 如果TRAN1行上有更新锁定,TRAN2无法获得更新锁定)。这使得"读取现有值,更新它,将其写回"原子操作,并防止两个事务同时在同一行上启动更新过程。

答案 1 :(得分:0)

更新(U)锁会自动放在UPDATE语句上的DB中的数据上。 主要任务是保护数据库中的数据不被多个事务同时更改,并避免死锁。

Update语句由3部分组成:读取数据,计算新值,写入数据。我们无法为阅读部分应用排他(X)锁。因此,Update锁并不是真正的独立锁,而是SHARED和EXCLUSIVE锁的混合。

假定两个进程都使用不同的访问路径来搜索要修改的同一资源(例如,Customers表中的同一客户行),并且它们都可以同时到达所需的资源。如果他们俩都在他们正在检查的数据上获得SHARED锁,那么他们都可以锁定要更改的资源,但是在进行修改之前,他们必须将其锁转换为EXCLUSIVE锁。由于其他进程将具有SHARED锁定,因此无法授予EXCLUSIVE锁定。每个进程都将具有SHARED锁,并且每个进程都将尝试将其更改为EXCLUSIVE锁,但是由于另一个进程的存在,两个进程均无法继续进行。这是一种僵局,称为“转换僵局”。

如果SQL Server使用UPDATE锁,则不会发生死锁。

UPDATE锁与SHARED锁兼容,但与EXCLUSIVE锁或其他UPDATE锁不兼容。因此,如果两个进程正在搜索相同的数据资源,则第一个到达该进程的资源将获得一个UPDATE锁,然后第二个进程将无法获得任何锁,而将等待第一个进程完成。由于第一个进程没有被阻止,因此它可以将其UPDATE锁定转换为EXCLUSIVE锁定,进行数据修改,并完成其事务并释放其锁定。然后第二个过程可以进行更改。

共享(S)锁-在需要读取对象时发生。

排他(X)锁-发生是为了防止其他事务修改或访问锁定的对象。