`
ijavagos
  • 浏览: 1241393 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

UPDATE 锁

阅读更多

UPDATE 锁并不是一种单独的锁类型,倒是有点像是SHAREDEXCLUSIVE锁的混合。并且可能与你认为的不同,UPDATE 锁不是由UPDATE操作获取的。 当SQL Server执行一个数据修改操作,但是需要首先执行一个检索来查找需要修改的资源时,事务会获取这种类型的锁。

SQL Server搜索时,它不需要获取EXCLUSIVE锁,只有在找到要更改数据时,才需要EXCLUSIVE锁。通常情况下,如果SQL Server进程只是搜索数据,它会在所访问到的每个资源上获取SHARED锁,然后确定是否已经找到了正在搜索的数据。但是,如果要搜索的数据是用来修改的话,SQL Server启用SHARED锁则存在潜在问题。例如,两个进程都是寻找相同的资源(如Customers表中同一客户行)进行修改,使用不同的访问的路径,并且它们在同一时间达到所需的资源。如果它们都在检索的数据上获取SHARED锁,它们都可以同时锁定要修改的资源,但在它们进行修改前需要将锁转换为EXCLUSIVE锁。 由于另一个进程具有了SHARED锁,则不会生成EXCLUSIVE锁。 每个进程都具有一个SHARED锁,并且每个都尝试将其转换为EXCLUSIVE的锁,但是都会由于另外一个进程的存在,这两个尝试都不会成功。这是一种死锁情况,叫做“转换死锁”。

UPDATE 锁是一种死锁避免机制。如果SQL Server使用UPDATE锁,则死锁将不会发生。 如果SQL Server进程开始了一个最终要修改数据的搜索操作,它获取UPDATE锁,直到找到要修改的数据。 UPDATE 锁与SHARED锁兼容,但与EXCLUSIVE锁或其他UPDATE锁不兼容。 因此,如果两个进程正在寻找相同的数据资源,则第一个到达的进程会获取到UPDATE锁,然后在第二个进程无法取得任何锁定,并且将等待第一个进程处理完成。由于第一个进程没有被阻塞,它可以将其UPDATE锁转换为EXCLUSIVE锁,并完成事务处理后释放锁,然后在第二个进程进行其他修改。

sys.dm_tran_locks 视图中,request_mode值为U的代表 UPDATE 锁。

来看一下UPDATE锁:

[我正在使用旧的示例数据库 pubs。 如果要尝试下面的代码可以单击这里下载]

-- Close all existing connections and start a new one

-- Step 1:
USE pubs;
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;


BEGIN TRAN;
UPDATE authors
SET contract = 0
WHERE au_lname = 'Ringer' ;

---- Step 2: Open a second connection window uncomment once,
-- so the ROLLBACK is still commented. Execute…

--USE pubs;
--SET TRANSACTION ISOLATION LEVEL READ COMMITTED ;

--BEGIN TRAN;
--UPDATE authors
--SET city = 'Provo'
--WHERE state = 'UT';

-- You should be blocked.

---- ROLLBACK TRAN;

-- Step 3: Go back to the first connection window and run the following
SELECT request_session_id AS session_id, DB_NAME(resource_database_id) AS [database],
request_mode AS mode, resource_type as [type],
resource_associated_entity_id AS entity,
resource_description, request_status AS status
FROM sys.dm_tran_locks;
COMMIT TRAN;

你将会得到类似下面的输出结果:

注意KEYWAIT状态的U锁,它具有与第一个连接所GRANTKEY相同的资源描述。现在COMMITROLLBACK第一个连接,你会看到第二个连接所等待的KEY上获得X锁,还有在另一个KEY上的X锁。

我提及UPDATE锁的目的是说明“修改数据的意向”,因此你可能会认为UPDATE的锁是类似于INIENT锁。 不是这样的,UPDATE锁指示一个更改锁锁模式的意向,而INTENT锁指示一个更改锁粒度的意向。

Kalen

分享到:
评论

相关推荐

    杀乐观锁,防止别人锁表,无法for update

    我用for update锁表修改数据,结果一直在执行,原来别人锁表了,导致我无法修改数据,用它能查出锁类型和谁锁的

    MySQL锁类型以及子查询锁表问题、解锁1

    FOR UPDATE`语句就是一种行级锁的用法,用于在更新数据前锁定选定的行,防止其他事务在此期间对这些行进行修改。当在查询条件中明确指定了主键,并且查询能够匹配到具体行时,InnoDB会实施行锁。例如: ```sql ...

    数据库oracle for update of和for update的区别

    ### 数据库Oracle锁:FOR UPDATE OF与FOR UPDATE的区别 在Oracle数据库中,为了确保数据的一致性和准确性,尤其是在多用户环境中进行并发操作时,锁机制是必不可少的一部分。本文将详细介绍`FOR UPDATE`与`FOR ...

    对oracle锁几种模式的理解

    ROW SHARE锁与SHARE UPDATE锁相同,主要是为了向后兼容早期版本的Oracle数据库。 - **应用场景**:当多个用户需要读取同一张表的数据时,可以使用ROW SHARE锁来避免锁冲突。例如,多个用户同时查询一张销售报表表...

    for_update_和_for_update_nowait_的区别

    当执行包含`FOR UPDATE`子句的`SELECT`语句时,Oracle会在所选择的行上放置排他锁(exclusive lock),即X锁,这种锁允许持有者读写数据,但阻止其他事务读写相同的行,直到原事务结束(通常是指提交或回滚)。...

    SQLITE数据库 UPDATE慢

    在SQLITE数据库中,UPDATE操作可能会遇到性能问题,导致更新速度缓慢。这通常是由于多种因素引起的,包括但不限于索引缺失、大数据量、触发器、事务处理、锁竞争以及查询优化等。下面我们将深入探讨这些因素,并提供...

    oracle执行update语句时卡住问题分析及解决办法

    这种只有update无法执行其他语句可以执行的其实是因为记录锁导致的,在oracle中,执行了update或者insert语句后,都会要求commit,如果不commit却强制关闭连接,oracle就会将这条提交的记录锁住。由于我的java程序...

    SQL Server分布式数据库的并发控制和故障恢复 (1).pdf

    SQL Server支持三种基本的封锁机制:排他锁(EX锁)、共享锁(SH锁)和更新锁(UPDATE锁)。若事务对某页加EX锁,则其它事务不能对此页加锁且不能读取或修改此页。若事务对某页加SH锁,则其它事务只能对该页加SH锁,且只能...

    你真的懂for update?(面试必备)

    2. 如果你发现使用Synchronized关键字处理线程安全问题不够理想,因为它基于悲观锁策略,可能导致较高的锁等待时间,并且在分布式系统中无法跨服务器保证锁的同步,这时"for update"就是一个可行的替代方案。...

    MySQL中update操作会自动加锁吗

    MySQL中update操作会自动加锁吗,看了就知道答案!!!

    各种类型数据库的死锁问题

    事务运行时间越长,其持有exclusive锁或update锁的时间便越长,从而堵塞了其他活动并可能导致死锁。 2. 尽可能按同一顺序访问数据对象。如果所有并发事务按同一顺序访问对象,则发生死锁的可能性会降低。 3. 避免...

    各种锁汇总,乐观锁、悲观锁、分布式锁、可重入锁、互斥锁、读写锁、分段锁、类锁、行级锁等

    FOR UPDATE`,在Java中,synchronized关键字和ReentrantLock的lock()方法都是悲观锁的例子。 3. **分布式锁**:在分布式系统中,由于进程间的内存不可见,需要一种跨节点的协调机制来实现锁。常见的分布式锁实现有...

    表级锁(TM锁) 表级锁(TM锁) 表级锁(TM锁) 表级锁(TM锁)

    - `SELECT * FROM FOR UPDATE`:加RS锁,允许RS、RX、S、SRX锁。 - `LOCK TABLE ... IN ROW SHARE MODE`:加RS锁,允许RS、RX、S、SRX锁。 - `LOCK TABLE ... IN ROW EXCLUSIVE MODE`:加RX锁,允许RS、RX锁。 - `...

    update语句的优化-oracle

    当需要分批更新大表时,可以结合ROWNUM限制每次更新的行数,避免一次性锁定大量行,从而减少锁竞争。 ```sql UPDATE (SELECT t.*, ROWNUM rnum FROM table_name t WHERE condition) t2 SET column_name = 'new_...

    oracle锁机制探讨

    2 SS(Row-S) 行级共享锁,其他对象只能查询这些数据行 Select for update、Lock for update、Lock row share 3 SX(Row-X) 行级排它锁,在提交前不允许做DML操作 Insert、Update、Delete and so on

    Hibernate update问题

    当你从数据库加载一个对象,修改其属性,然后调用`update()`方法,Hibernate会根据对象的状态自动执行相应的SQL UPDATE语句。然而,如果对象不在Session缓存中,`update()`方法可能会失效,因为Hibernate无法跟踪...

    美式插芯锁与中国标准之对比-Update

    美式插芯锁与中国标准之对比-Update

    thinkPHP框架乐观锁和悲观锁实例分析

    在ThinkPHP中,可以通过SQL语句的“FOR UPDATE”子句来实现悲观锁,这样可以保证在当前事务完成之前,其他事务无法修改加锁的数据行。 在使用悲观锁时,通常需要先对需要操作的数据行进行查询,并在查询的同时对...

    Vastbase G100锁机制

    ROW SHARE 锁模式是次弱的锁模式,SELECT FOR UPDATE 和 SELECT FOR SHARE 命令在目标表上取得一个这种模式的锁,ROW SHARE 锁模式与 EXCLUSIVE 和 ACCESS EXCLUSIVE 锁模式冲突。 ROW EXCLUSIVE 锁模式是次强的锁...

Global site tag (gtag.js) - Google Analytics