首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >更新锁用于什么?

更新锁用于什么?
EN

Stack Overflow用户
提问于 2014-06-07 07:01:01
回答 2查看 3.6K关注 0票数 3

我在读理解SQL Server中的锁定。但我不太明白更新锁的目的。

详情如下:

更新锁 Update (U)锁防止常见的死锁形式。典型的更新模式包括读取记录的事务,获取资源(页或行)上的共享(S)锁,然后修改行,这需要将锁转换为独占(X)锁。如果两个事务获取资源上的共享模式锁,然后尝试并发更新数据,则有一个事务尝试将锁转换为独占(X)锁。共享模式到独占锁转换必须等待,因为一个事务的独占锁与另一个事务的共享模式锁不兼容;出现锁等待。第二个事务试图获取用于更新的独占(X)锁。因为两个事务都在转换为独占(X)锁,而且它们都在等待另一个事务释放其共享模式锁,因此会出现死锁。 为了避免这个潜在的死锁问题,使用update (U)锁。一次只有一个事务可以获得资源的update (U)锁。如果事务修改了资源,则update (U)锁将转换为独占(X)锁。否则,锁将转换为共享模式锁.

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

在TRAN1中在SQL下面执行。

代码语言:javascript
复制
BEGIN TRAN
SELECT BrandName FROM dbo.Brand WHERE BrandId=2

现在,TRAN1授予用于RID的S锁

在TRAN2中在SQL下面执行

代码语言:javascript
复制
 BEGIN TRAN
 SELECT BrandName FROM dbo.Brand WHERE BrandId=2

现在,TRAN2为与TRAN1相同的RID资源授予S锁

在TRAN1中在SQL下面执行

代码语言:javascript
复制
UPDATE dbo.Brand SET BrandName='YBrand' WHERE BrandId=2

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

在TRAN2中在SQL下面执行

代码语言:javascript
复制
UPDATE dbo.Brand SET BrandName='ZBrand' WHERE BrandId=2

然后出现死锁。

向上死锁与U锁用于防止的描述完全相同。但僵局仍在发生。

所以我的问题是:你和X锁有什么不同?哪种情况可以防止死锁而不是使用X锁?

EN

回答 2

Stack Overflow用户

发布于 2014-06-07 07:17:24

UPDATE操作是一个两步的过程:

  1. 首先使用(U) (update)锁读取现有值
  2. 然后,将该锁转换为独占的(X)锁,以回写新的(更新的)值。

由于您的REPEATABLE READ隔离级别,并且您已经像这样安排了语句,是的,您将陷入死锁。但我真的不明白这跟update锁有什么关系.(这确实是因为您已经像这样安排了代码,并且使用了REPEATABLE READ)。

(U)锁的主要“好处”是在那个时候其他的(S)共享锁仍然是可能的。例如,当一个事务读取要用(U)锁更新的值时,另一个事务可以使用SELECT中的(S)共享锁读取相同的值(如果您有独占的(X)锁,例如,当您执行DELETE时)

如果有两个单独执行UPDATE的事务(没有SELECTREPEATABLE READ),那么第一个事务所采取的(U)锁将阻止第二个事务也读取该值(因为(U)锁是不兼容的--如果TRAN1在一行上有一个更新锁,TRAN2就无法获得它的更新锁)。这使得“读取现有值、更新它、写回它”成为一个原子操作,并防止两个事务同时在同一行上启动更新进程。

票数 4
EN

Stack Overflow用户

发布于 2019-12-05 13:13:54

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

Update语句由三个部分组成:读取数据、计算新值、写入数据。我们不能为阅读部分申请排他的(X)锁。因此,Update锁实际上不是一种单独的锁,而是共享锁和排他锁的混合体。

假设两个进程都在使用不同的访问路径搜索要修改的相同资源(例如,Customers表中的相同客户行),并且它们都可以同时到达所需的资源。如果他们都在获取他们正在检查的数据上的共享锁,他们都可以锁定他们想要更改的资源,但是在进行修改之前,他们必须将他们的锁转换成一个排他锁。由于其他进程将具有共享锁,因此不能授予独占锁。每个进程都有一个共享锁,每个进程都试图将其更改为独占锁,但由于另一个进程的存在,这两个进程都无法继续。这是一种死锁情况,称为“转换死锁”。

如果Server使用更新锁,则不会发生死锁。

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

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

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

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24094663

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档