并发下的死锁问题

摘要:
在写这篇文章之前,我很傻地认为死锁只能是经典的:session1 session2 update select select update并没有解释很多教科书上的经典案例,对SQL的理解也逐渐加深。遇到的案件也在增加。今天,我们共享同一张桌子。类型2更新语句使用不同的索引,导致在大量并发情况下出现死锁。

    写本文之前我还傻傻的以为死锁只能是那种经典:

    session1  session2

    update    select

    select    update

    不多说明了教科书般的经典案例,对SQL 的理解逐渐深入,遇到的案例也不断增加今天来分享一个同一张表2类update 语句使用不同索引,在大量并发下导致的死锁。

    废话不多说直接开整!

   

    -------------------------------------转载请注明出处------------http://www.cnblogs.com/double-K/p/5036606.html------------------

    先创建一张测试表table_1

CREATE TABLE [dbo].[Table_1](
    [a] [int] NULL,
    [b] [nchar](10) NULL,
    [c] [nchar](10) NULL,
    [d] [nchar](10) NULL,
    [e] [uniqueidentifier] NULL,
    [f] [nchar](10) NULL
) ON [PRIMARY]

    插入测试数据

    

declare @a int 
set @a = 0
while @a < 1000
begin 
insert into table_1
select @a ,'1','2','3',newid(),'test'
set @a = @a + 1

end 

    创建索引,在e列(newid) 上创建聚集索引,在a 列 创建非聚集索引 包含列b

    

/****** Object:  Index [NonClusteredIndex-20151210-152313]    Script Date: 2015/12/10 15:34:50 ******/

CREATE CLUSTERED INDEX [ClusteredIndex-20151210-152411] ON [dbo].[Table_1]
(
    [e] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [NonClusteredIndex-20151210-152313] ON [dbo].[Table_1]
(
 [a] ASC
)
INCLUDE (  [b]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO

    -----------------------------准备工作就绪----------------------------

    下面来说一下这个死锁的模拟 :

    一个session利用a列的非聚集索引更新数据

    一个session 利用e列聚集索引扫描更新数据

    下面我们看一下测试的语句:

    

------使用索引查找
update table_1 set b = 'i' where a in (294,184,197,894)
and c ='2'
------聚集索引扫描update table_1  set b = 'u' where a in (294,184,197,894,6,7,8,9,10,13,154,234,654,213,76,98,345,213,543,3,33,333,55,689,90,99,999,56,4,35,789,43,123)
and c ='2'

    执行计划:

    并发下的死锁问题第1张

    

    开2个窗口分别运行:

    

while 1=1
begin 
update table_1  set b = 'u' where a in (294,184,197,894,6,7,8,9,10,13,154,234,654,213,76,98,345,213,543,3,33,333,55,689,90,99,999,56,4,35,789,43,123)
and c ='2'
end
while 1=1
begin
update table_1 set b = 'i' where a in (294,184,197,894)
and c ='2'
end

    使用profiler 抓取死锁信息:使用locks的模板就可以 ,建议去掉两个strating 记录太多。

    并发下的死锁问题第2张

 -------------------------------------转载请注明出处------------http://www.cnblogs.com/double-K/p/5036606.html------------------

    运行两个语句 查看死锁信息:

    并发下的死锁问题第3张

    session 56 拥有聚集索引上的X锁,去申请 非聚集索引上的X锁的同时,session 55拥有非聚集索引的U锁,去申请聚集索引的U锁而造成了死锁的情况,这个问题可以看出在in的条件数量多的时候 优化器选择了聚集索引扫描,更新数据及索引(聚集索引和非聚集索引),而数量少的时候使用非聚集索引扫描查找,更新数据及索引(聚集索引和非聚集索引)。

    创建索引以及业务设计的时候要多考虑一下应用的场景避免这种。

    出现这种问题要怎么解决呢?

    1.提高或降低隔离级别,不推荐...治标不治本的方法。

    2.找出问题的根源,如本例中如果都使用聚集索引的扫描或非聚集索引的查找,调整索引的使用。

    

    

-------------------------------------转载请注明出处------------http://www.cnblogs.com/double-K/p/5036606.html------------------

    

免责声明:文章转载自《并发下的死锁问题》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇本地idea开发mapreduce程序提交到远程hadoop集群执行机器学习ROC图解读下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Mysql常用命令操作小结

Mysql操作大全 一、概述     SQL(Structured Query Language)语言的全称是结构化查询语言。数据库管理系统通过SQL语言来管理数据库中的数据。     SQL语言分为三个部分:数据定义语言(Data DefinitionLanguage,简称为DDL)、数据操作语言(DataManipulation Language,简称...

【quartz】 各数据库创建脚本

QRTZ_CALENDARS 以 Blob 类型存储 Quartz 的 Calendar 信息 QRTZ_CRON_TRIGGERS 存储 Cron Trigger,包括 Cron表达式和时区信息 QRTZ_FIRED_TRIGGERS 存储与已触发的 Trigger 相关的状态信息,以及相联 Job的执行信息 QRTZ_PAUSED_TRIGGER_GR...

Sql Server查询性能优化之走出索引的误区

据了解绝大多数开发人员对于索引的理解都是一知半解,局限于大多数日常工作没有机会、也什么没有必要去关心、了解索引,实在哪天某个查询太慢了找到查询条件建个索引就ok,哪天又有个查询慢了,再建立个索引就是,或者干脆把整个查询SQL直接发给DBA,让DBA直接帮忙优化了,所以造成的状况就是开发人员对于索引的理解、认识很局限,以下就把我个人对于索引的理解及浅薄认识...

PowerDesinger15设置字体大小

使用PowerDesigner时,它默认table的字体大小颜色等很难看; 假设通过 Symbol ---> Format进行设置。仅仅能对选中的最改动,新建的Table无效。能够通过例如以下改动。让你的设置永久保存: Tools -----> Display Preference.... ------> Format ------...

Spring Boot集成thymeleaf异步刷新页面

 现在比较流行前后端分离开发,但在有些业务场景下模板引擎也用的不少。本文介绍thymeleaf页面的局部更新,Spring Boot采用的是2.0.4,先来看代码。 IndexController.java: package com.example.demo.thymeleaf; import org.springframework.stereoty...

Python 操作GridFS

importpymongo from pymongo importMongoClient from gridfs importGridFS classGFS(object): def __init__(self, file_db,file_table): self.file_db =file_db self.file...