首页 > 其他 > 详细

更新一张没有主键的数据表,引发的死锁

时间:2014-05-26 19:18:12      阅读:820      评论:0      收藏:0      [点我收藏+]

不介绍背景,直接上例子

首先我们创建这样的一张表,没有主键,添加下面的数据

bubuko.com,布布扣

 

然后我们分别创建下面的连个连接查询

查询1:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
--SERIALIZABLE
--READ UNCOMMITTED
begin tran
print convert(nvarchar(30),convert(datetime,getdate(),121),121)

update table1
set A=‘aa‘
where B=‘b2‘

-- print convert(nvarchar(30),convert(datetime,getdate(),121),121)
waitfor delay ‘00:00:10‘
update table1
set A=‘aa‘
where B=‘b4‘
--EXEC sp_lock2 @@spid
EXEC sp_lock @@spid
print convert(nvarchar(30),convert(datetime,getdate(),121),121)
commit tran

查询2:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
--DBCC USEROPTIONS
--begin try
begin tran
print convert(nvarchar(30),convert(datetime,getdate(),121),121)
update table1
set A=‘aa‘
where B=‘b8‘

--EXEC sp_lock2 @@spid
waitfor delay ‘00:00:5‘
EXEC sp_lock @@spid
print convert(nvarchar(30),convert(datetime,getdate(),121),121)
commit tran

首先执行查询一,然后马上切换到查询二

再马上暂停查询二,执行 

EXEC sp_lock @@spid

发现结果是:

bubuko.com,布布扣

最后一条记录对应的就是table1,这时我们会看到在table1上已经加上了表的意向锁。

如果不做停止操作,执行的结果不会有异常。

然后我们再调整一下查询2:

update table1 
set A=‘aa‘
where B=‘b1‘

重复上面的步骤会发现执行的锁信息如下:

bubuko.com,布布扣

 

这时我们会发现执行的结果出现异常

消息 1205,级别 13,状态 45,第 6 行
事务(进程 ID 53)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务。

其中有一个规律,我们查询一中有B=‘b2‘,如果查询二中的条件值在b2之前就会出现死锁,而在b2之后就会正常执行事务。

我们来看一下查询一,在执行过程中的锁信息:

bubuko.com,布布扣

 

当执行查询一的过程中,再执行查询二,对于第一种情况,将整个表加上了意向锁,等待查询一结束释放资源后再

执行查询二,而对于第二种情况则出现了资源的争夺,导致死锁。

在这个过程中我们看到了IX,IX是意向锁,什么是意向锁呢?
意向锁的含义是如果对一个结点加意向锁,则说明该结点的下层结点正在被加锁;对任一结点加锁时,必须先对它的上层结点加意向锁。

当我们给行记录加上X锁的时候,就会在page和TAB上加意向锁。

例如,对任一元组加锁时,必须先对它所在的关系加意向锁。

于是,事务T要对关系R1加X锁时,系统只要检查根结点数据库和关系R1是否已加了不相容的锁,而不再需要搜索和检查R1中的每一个元组是否加了X锁。

bubuko.com,布布扣bubuko.com,布布扣

 

待续。。。

更新一张没有主键的数据表,引发的死锁,布布扣,bubuko.com

更新一张没有主键的数据表,引发的死锁

原文:http://www.cnblogs.com/wanglg/p/3751895.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!