Updlock 与 Holdlock

记录一下对问题的探索,顺便回答一下自己提出的问题:http://q.cnblogs.com/q/72033/

本人菜鸟,看了这篇文章:http://www.cnblogs.com/adforce/archive/2011/04/20/2021929.html 后对锁和事务隔离级别有了基本的了解。

然后对自己提出的问题的探索中,又看到了这篇文章:http://www.cnblogs.com/xwdreamer/archive/2012/09/19/2694161.html  对意向锁也有了更深一步的了解。

感谢以上两位博主的分享。

好,回到对自己问题的解答:

表结构

A  B

1   2 
3   4

事务一:

begin tran

select * from dbo.Lock1 with(updlock) where a=‘1‘ 
waitfor delay ‘00:00:05‘

rollback

事务二:

begin tran

select * from dbo.Lock1 with(holdlock) where a=‘1‘

rollback

执行 sp_lock 查看信息。

首先,先单独查看使用updlock 的信息

begin tran

select * from dbo.Lock1 with(updlock) where a=‘1‘ 
waitfor delay ‘00:00:05‘

rollback

注意:这里申请了TAB的IX锁

关注61进程

然后再单独查看使用HoldLock的信息

begin tran

select * from dbo.Lock1 with(HoldLock) where a=‘1‘ 
waitfor delay ‘00:00:05‘

rollback

注意:这里申请了TAB的S锁

关注60进程

对于自己之前提出来的问题:

U锁与S锁不是不冲突的吗?

为什么事务二会等到事务一执行完毕才能执行?

之前的想法:知道U锁与S锁不冲突,事务一只加上了U锁,事务二只想加上S锁,为什么就会阻塞呢?

后来查阅了更多的资料,发现之前自己的想法只是停留在 锁发生在 RID 的局限上。 MSDN:https://msdn.microsoft.com/zh-cn/library/ms187749.aspx

但是事务一和事务二之间发生的阻塞存在于 RID,PAG和,TAB    或者其他更多。

----------------------------------------------------------------------------------------------------

锁的请求状态:

CNVRT:锁正在从另一种模式进行转换,但是转换被另一个持有锁(模式相冲突)的进程阻塞。

GRANT:已获取锁。

WAIT:锁被另一个持有锁(模式相冲突)的进程阻塞。

------------------------------------------------------------------------------------------------------

执行事务一和事务二:

根据上面两次单独的信息查看

事务一申请了TAB的IX锁,事务二申请TAB的S锁。

事务一先申请了TAB的IX锁,事务二过来先申请了IS锁,然后想由IS锁上升到S锁,但是IX锁与S锁是冲突的  红色框住:CNVT

所以阻塞了。。。

上面是先执行Updlock再执行HoldLock

以下是反过来的:

先申请TAB IS锁 ,后想申请IX锁,IS锁和IX也是冲突的。红色框住:WAIT

以上只是个人的理解,如果哪里有理解不正确或者用词不当的地方,希望有心人帮我指出。在此谢过!

时间: 2024-11-07 05:29:21

Updlock 与 Holdlock的相关文章

WITH (UPDLOCK,HOLDLOCK)提示与不同表类型

WITH (UPDLOCK,HOLDLOCK)提示与不同表类型 我们先来了解下UPDLOCK和HOLDLOCK的概念. UPDLOCK 指定采用更新锁并保持到事务完成. UPDLOCK 仅对行级别或页级别的读操作采用更新锁. 如果将 UPDLOCK 与 TABLOCK 组合使用或出于一些其他原因采用表级锁,将采用排他 (X) 锁. HOLDLOCK 等价于SERIALIZABLE.保持共享锁直到事务完成,使共享锁更具有限制性:而不是无论事务是否完成,都在不再需要所需表或数据页时立即释放共享锁.并

sqlserver 中NOLOCK、HOLDLOCK、UPDLOCK、TABLOCK、TABLOCKX

发表于3年前 ⁄ SQL Server ⁄ 暂无评论 ⁄ 阅读量 3,483 NOLOCK(不加锁) 此选项被选中时,SQL Server 在读取或修改数据时不加任何锁. 在这种情况下,用户有可能读取到未完成事务(Uncommited Transaction)或回滚(Roll Back)中的数据, 即所谓的“脏数据”. HOLDLOCK(保持锁) 此选项被选中时,SQL Server 会将此共享锁保持至整个事务结束,而不会在途中释放. UPDLOCK(修改锁) 此选项被选中时,SQL Serve

sqlserver 中的NOLOCK、HOLDLOCK、UPDLOCK、TABLOCK、TABLOCKX

1.NOLOCK(不加锁) 此选项被选中时,SQL Server 在读取或修改数据时不加任何锁. 在这种情况下,用户有可能读取到未完成事务(Uncommited Transaction)或回滚(Roll Back)中的数据, 即所谓的“脏数据”. 2.HOLDLOCK(保持锁) 此选项被选中时,SQL Server 会将此共享锁保持至整个事务结束,而不会在途中释放. 3.UPDLOCK(修改锁) 此选项被选中时,SQL Server 在读取数据时使用修改锁来代替共享锁,并将此锁保持至整个事务或命

sqlserver-一次updlock和withnolock和with check option 的报错原因分析

接口程序一直运行的很稳定,其中有一天进行了数据库的整改,导致程序不断报错, 报错信息如下 原因: 程序代码写入以下代码 select * from ViewName with(updlock) where XXX 而数据库的这个view代码如下 select * from tableName with(nolock) where XX 只要执行这个查询,就会导致以上错误,以上错误代码,一个需要加锁,一个不需要加锁,故报错了 故将数据库的view进行这样写 select * from tableN

SqlServer中的更新锁(UPDLOCK)

优点: 允许读取数据(不阻塞其它事务)并在以后更新数据,同时确保自从上次读取数据后数据没有被更改 当用UPDLOCK来读取记录时可以对取到的记录加上更新锁,从而加上锁的记录在其它的线程中是不能更改的只能等本线程的事务结束后才能更改 begin transelect * from address WITH (UPDLOCK) where [Name]='Z'waitfor delay '00:00:10' update address set [Name]='ZZ'commit tran 注意:

使用Sqlserver更新锁防止数据脏读

有时候我们需要控制某条记录在程序读取后就不再进行更新,直到事务执行完释放后才可以.这时候我们就可以将所有要操作当前记录的查询加上更新锁,以防止查询后被其它事务修改.这种操作只锁定表中某行而不会锁定整个表,体验更好. 测试sql代码如下: 在一个查询中执行如下语句 begin tran SELECT InvestState FROM InvestOrdersABC WITH (UPDLOCK) where id=10005 waitfor delay '00:00:10' update Inves

【转】数据库锁机制

1 前言 数据库大并发操作要考虑死锁和锁的性能问题.看到网上大多语焉不详(尤其更新锁),所以这里做个简明解释,为下面描述方便,这里用T1代表一个数据库执行请求,T2代表另一个请求,也可以理解为T1为一个线程,T2 为另一个线程.T3,T4以此类推.下面以SQL Server(2005)为例. 2 锁的种类 共享锁(Shared lock). 例1: ---------------------------------------- T1: select * from table (请想象它需要执行

sql语句对数据库表进行加锁和解锁

锁是数据库中的一个非常重要的概念,它主要用于多用户环境下保证数据库完整性和一致性. 我们知道,多个用户能够同时操纵同一个数据库中的数据,会发生数据不一致现象.即如果没有锁定且多个用户同时访问一个数据库,则当他们的事务同时使用相同的数据时可能会发生问题.这些问题包括:丢失更新.脏读.不可重复读和幻觉读: 1.当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,会发生丢失更新问题.每个事务都不知道其它事务的存在.最后的更新将重写由其它事务所做的更新,这将导致数据丢失.例如,两个编辑人员制作了

数据提高查询速度的方法(摘抄)

处理百万级以上的数据提高查询速度的方法: 1.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描. 2.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 3.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:     select id from t where num is null     可以在num上设置默认值0,确保表中num列没有