搜索
简帛阁>技术文章>sql server的UPDLOCK、HOLDLOCK试验

sql server的UPDLOCK、HOLDLOCK试验

-- 2个tran都查询id = 1000001数据,然后尝试更新
-- 结果2边都能在10s内结束
BEGIN TRAN
SELECT * FROM content_article where id = '1000001';
WAITFOR DELAY '00:00:10'
UPDATE content_article SET weighted = 2 where id = '1000001';
COMMIT TRAN

-- 查询时都加上HOLDLOCK, 左边先运行
-- 结果:左边18s结束,右边12s结束
-- 右边报错:事务(进程 ID 58)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务。
BEGIN TRAN
SELECT * FROM content_article with (HOLDLOCK) where id = '1000001';
WAITFOR DELAY '00:00:10'
UPDATE content_article SET weighted = 2 where id = '1000001';
COMMIT TRAN

-- 左边不变,右边加上UPDLOCK
-- 结果:同上-----------应该说明右边并没有活动UPDLOCK吧
BEGIN TRAN
SELECT * FROM content_article with (HOLDLOCK) where id = '1000001';
WAITFOR DELAY '00:00:10'
UPDATE content_article SET weighted = 2 where id = '1000001';
SELECT * FROM op_content_article where id = '1000001';
COMMIT TRAN

推测:
1.因为数据库默认 隔离级别 读已提交,故select语句只是S锁,不加HOLDLOCK,二边事务正常运行;
2.加了HOLDLOCK,首次select的语句会获得UPDLOCK, 故发生死锁时,未获得UPDLOCK报错了,即右边后面2次都无法获得UPDLOCK

实际:如官方文档所示,sql server 死锁监视器会定期检查 陷入死锁的任务,检测到了循环依赖关系,选择其中一个任务作为牺牲品,终止并提示错误

再举一个具体的例子详细说明:

-- 事务1先获得row1共享锁
-- 事务2获得row2共享锁
-- 事务2尝试获得row1排他锁---但事务1的共享锁阻止了
-- 事务1尝试获得row2排他锁---但事务2的共享锁阻止了

-- 事务1和事务2互相死锁,被死锁监视器检测到,故10s左右 两边都会执行完毕;
BEGIN TRAN
SELECT * FROM content_article (HOLDLOCK) where id = '1000001';
WAITFOR DELAY '00:00:10'
UPDATE content_article SET weighted = 2 where id = '1000002';
COMMIT TRAN

ROLLBACK TRAN
BEGIN TRAN
SELECT * FROM content_article with (HOLDLOCK) where id = '1000002';
UPDATE content_article SET weighted = 2 where id = '1000001';
COMMIT TRAN
2个tran都查询id1000001数据,然后尝试更新结果2边都能在10s内结束BEGINTRANSELECT*FROMcontent_articlewhereid1000001;WAITFORDEL
记录一下对问题探索,顺便回答一下自己提出问题:http://qcnblogscom/q/72033/本人菜鸟,看了这篇文章:http://wwwcnblogscom/adforce/archiv
NOLOCK(不加锁)此选项被选中时,SQLServer在读取或修改数据时不加任何锁。在这种情况下,用户有可能读取到未完成事务(UncommitedTransaction)或回滚(RollBack)中
回到目录对于高并发场合下,使用UPDLOCK可以有效控制并发更新问题,即当一个线程在进行with(UPDLOCK)并进行update时,另一个线程将被阻塞,它会等第一个线程更新结束后,才可以进行
SqlServer为每个触发器都创建了两个专用表:Inserted表和Deleted表。这两个表由系统来维护,它们存在于内存中而不是数据库中。这两个表结构总是与被该触发器作用结构相同,触发器执
在初期工作中,要做一个系统登录验证,翻阅同事做登录验证,发现同事们做用户名验证时,查结果集来自一个视图,之前也弄过视图,但很少去仔细看过有关方面详细知识,于是特意百度谷歌了一下,总结如下知识
1SQLSERVER数据类型数据类弄是数据一种属性,表示数据所表示信息类型。任何一种计算机语言都定义了自己数据类型。当然,不同程序语言都具有不同特点,所定义数据类型各类和名称都或多或少
SqlServer游标使用一、TSQL和SQL区别SQL是StructruedQueryLanguage缩写,即结构化查询语言。1987年,“国际标准化组织(ISO)”把ANSISQL作为国际标
第一类、根据申请方式分:commit型它是指先reserve申请一大块,再通过commit提交后得到空间。这种方式申请到空间可以启用awe!stolen型与commit相对应!它不用reserve
1阻塞除了内存、CPU、I/O这些系统资源以外,阻塞和死锁是影响数据库应用性能另一大因素。所谓「阻塞」,是指当一个数据库会话中的事务,正在锁定其他会话事务想要读取或修改资源,造成这些会话发出