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

不介绍背景,直接上例子

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

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

查询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

发现结果是:

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

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

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

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

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

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

消息 1205,级别 13,状态 45,第 6

事务(进程 ID 53)与另一个进程被死锁在 锁
资源上,并且已被选作死锁牺牲品。请重新运行该事务。

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

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

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

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

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

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

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


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

待续。。。

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

时间: 2024-11-04 19:40:22

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

8.自增主键 插入指定主键的数据

假设你有一个表Authors ,主键是AuthorId Author author = new Author() { AuthorId = 1001, Name = "Johny", Books = new List<Book> { new Book() { Title = "Learn VB.NET"}, new Book() { Title = "C# Fundamentals for Absolute Beginners"},

向Mysql主键自增长表中添加数据并返回主键

表level,其主键为lid 1.select max(id) from table 查询语句:SELECT MAX(lid) FROM LEVEL 返回插入主键 2.select LAST_INSERT_ID(id) from table 查询语句:SELECT LAST_INSERT_ID(lid) FROM LEVEL; 返回主键列表,最后一个值为插入主键 3.select @@identity from table 查询语句:SELECT @@identity FROM level 返回

Mysql增加主键或者更改表的列为主键的sql语句

最近在整理关于MySql的东西,把一些需要记录的东西写下来,以便以后查询和浏览,以下是一些操作技巧. 添加表字段 alter table table1 add transactor varchar(10) not Null; alter table   table1 add id int unsigned not Null auto_increment primary key 修改某个表的字段类型及指定为空或非空 alter table 表名称 change 字段名称 字段名称 字段类型 [是否

Yii——关于无主键的数据表或视图

使用 yii 写 restful api 时,有一个数据库视图因为没有主键而不能被正确的按主键查询.通常情况下可以通过类似 ViewName::findOne(['primaryKey' => 1]) 的方法,指定一个查询字段. 但是这不是最方便的解决办法,我们可以在模型(Model)中可以手动设置一个主键,然后就可以愉快的使用 ViewName::findOne(1) 查询了: 错误示例 public static function primaryKey() { return 'primary

Oracle数据表中的死锁情况解决方法

不知道干了啥,把数据表锁住了,没法update. 百度了各种方法,总结如下. 查看被锁住的表(两句都可以): select * from v$session t1, v$locked_object t2 where t1.sid=t2.SESSION_ID   select sess.sid, sess.serial#, lo.oracle_username, lo.os_user_name, ao.object_name, lo.locked_mode from v$locked_object

一张6亿条数据表引发的事故

业务人员告诉我某系统磁盘IO持续高达300MB/s,系统平台为AIX,遂 topas 查看果然如此. 用下面脚本到Oracle数据库中看了一下: SELECT Disk_Reads DiskReads, Executions, SQL_ID, SQL_Text SQLText, SQL_FullText SQLFullText FROM ( SELECT Disk_Reads, Executions, SQL_ID, LTRIM(SQL_Text) SQL_Text, SQL_FullText,

请教:.net实体框架中有外键关系数据表的数据显示

如图,这是一个一对多的简单数据框架 现在知道一个Item对象,如何获取它对应的category对象? 我试过,item.categoryReference.Value 和 item.category 好像都不行,提示"未将对象引用设置到对象的实例"错误. 在此请教各位...

mysql 查询某一主键在那些表中中被设置为外键了

use information_schema; show tables; select * from KEY_COLUMN_USAGE where COLUMN_NAME='areaid';

数据库设计中主键问题

转自: http://www.jb51.net/article/40933.htm 数据库主键在数据库中占有重要地位.主键的选取策略决定了系统是否可靠.易用.高效.本文探讨了数据库设计过程当中常见的主键选取策略,并剖析了其做主键的优缺点,提出了相应的解决问题的方法 在基于关系型数据库设计时候,通常要为每张表指定一个主键,所谓主键就是能够唯一标识表中某一行记录的属性或属性组,一个表只能有一个主键,但可以有多个候选索引.因为主键可以唯一标识某一行记录,所以可以确保执行数据更新.删除.修改时不出现错误