原文地址:http://www.cnblogs.com/nzperfect/archive/2011/09/26/2192006.html

最近遇到一个update时产生死锁的情况,两条一模一样的sql同时执行时,居然会产生Deadlock。

windows 2003 server x64 + sql server 2008 sp2 Enterprise X64

示例(实际环境与该表相似):

当两个进程同时执行下面的语句时,在高并发下会产生死锁:

update tt with(rowlock) set c='eb',d='cc' 
where a='84B23855-2155-4EE0-911D-38D1265F1655'

示例表结构:

use tempdb
go
create table tt(id int identity primary key,a char(36),b char(36),c varchar(max) ,d char(200))
go
insert into tt select NEWID(),'bbb','ccc','ddd'
go 10000

create index ix_a_bc on tt(a)include(b,c)

使用profiler查看update时,锁请求释放情况:

新开一个会话,在我这里spid=58

update tt with(rowlock) set c='eb',d='cc' 
where a='84B23855-2155-4EE0-911D-38D1265F1655'

通过profiler观察:

由上图可以看到,update语句首先通过非聚集索引ix_a_bc找到a值为84B23855-2155-4EE0-911D- 38D1265F1655的hash键值是2b02a7cba37c的记录,并加U锁,然后通过该索引上的定位符找到聚集键520072b6acb1,并 加U锁,之后再加X锁,再为2b02a7cba37c加x锁,在这个过程中,为非聚集键及聚集键加了U锁和X锁,其它想update该记录的会话,只能等 待,这样更新完后将释放所有锁。

下面我们为该表再加一索引:

create index ix_b_cd on tt(b)include(c,d)

再次执行上面的update语句,通过profiler观察:

通过上图,可以看到在得到聚集键520072b6acb1并为之加U/X锁之后,居然释放掉了非聚集索引键2b02a7cba37c上的U锁,释放之后又再一次的重新获取2b02a7cba37c上的X锁,试想如果在它释放2b02a7cba37cU锁到重新获取x锁这个时间差之间,其它update该行的进程插进来取得2b02a7cba37c上的U锁,将会怎么样?

下面开始测这个情况,在两个会话中执行下面的sql语句,同时更新,在我这里是spid为54 /58 .

通过上图,我们发现,产生了死锁,产生死锁后,进程54成为牺牲品,下面看用sql profiler抓到的情况:

由上图可以看到,两个进程同时执行,进程54首先获取到了非聚集键2b02a7cba37c上的U锁,然后得到聚集键520072b6acb1,并 为之加U锁和X锁,接下来进程54释放掉了2b02a7cba37c上的U锁,此时进程58插入进来,获取了该2b02a7cba37c上的U锁,接下来 进程58的动作肯定是要获取聚集键520072b6acb1上的U锁,然而,聚集键520072b6acb1被进程54加了X锁并未释放,所以无法获取, 而进程54接下来又要重新获取2b02a7cba37c上的X锁,而2b02a7cba37c又被进程58加了U锁,互相等待,产生死锁,如下图:

在这种情况下,SQL会发现产生Deadlock,自动kill掉一个进程,在本示例中,54进程被kill掉,58进程获取取到聚集键 520072b6acb1上的U锁,然后加X锁,然后释放掉了2b02a7cba37c上的U锁,并再为之加上X锁,再之后释放掉全部锁,进程58完成更 新。如下图:

正常情况下,对同一行执行相同的update时,不会产生死锁,本案例会产生死锁的原因是在获取了非聚集键的U锁,继续要更新非聚集索引时,居然释放了该 键上的U锁,而去重新获取X锁,经过反复测试,发现满足下面的情况时,就会发生这种情况:非聚集索引include列有varchar(max)字段,并 且在update时要更新该字段,而且在这个表里,必须要有两个(多于两个)include该varchar(max)字段的非聚索引时,就会发生。

这是bug,还是故意为之?为何要针对varchar(max)会有此不同?

转载于:https://www.cnblogs.com/fcsh820/p/3147433.html

(转)令人无法理解的死锁案例分析相关推荐

  1. RFM模型的理解和python案例分析

    RFM模型是什么 RFM是客户关系管理(CRM:Customer Relationship Management)中一种重要的分析模型,通过研究一个客户的交易时间.交易频率和交易总金额来衡量客户的价值 ...

  2. 由MySQL加锁机制引发的死锁案例分析

    ​ 1.死锁案例 --建表 CREATE TABLE t1(`id` int(11) NOT NULL,`value` int(11) NOT NULLPRIMARY KEY (`id`),KEY ` ...

  3. mysql先删后增并发时出现死锁_MySQL死锁案例分析一(先delete,再insert,导致死锁)...

    一.死锁案例 MySQL版本:Percona MySQL Server 5.7.19 隔离级别:可重复读(RR) 业务逻辑:并发下按某个索引字段先delete记录,再insert记录 比如:begin ...

  4. Mysql死锁案例分析

    前言 通过<mysql锁机制>初步了解mysql的锁机制,通过几个死锁场景分析更加深入了解锁. 场景1: 唯一索引批量插入,引起的插入间隙死锁. // 隔离级别RCCREATE TABLE ...

  5. java并发,同步synchronize和lock锁的使用方法和注意,死锁案例分析

    1.什么是线程安全问题 多个线程同时共享同一个全局变量或者静态变量的时候,某个线程的写操作,可能会影响到其他线程操作这个变量.所有线程读一个变量不会产生线程安全问题. 实际场景就是火车站买票问题:剩余 ...

  6. MySQL批量更新死锁案例分析--转载

    问题描述 在做项目的过程中,由于写SQL太过随意,一不小心就抛了一个死锁异常,如下: [java] view plaincopyprint? com.mysql.jdbc.exceptions.jdb ...

  7. MySql批量更新死锁案例分析

    http://blog.csdn.net/aesop_wubo/article/details/8286215 问题描述 在做项目的过程中,由于写SQL太过随意,一不小心就抛了一个死锁异常,如下: 表 ...

  8. 实战演练丨Oracle死锁案例分析,看完你就懂了

    问题背景 发生Oracle死锁的多个进程执行的都是同一个存储过程,大概代码及顺序如下: --1.首先通过主键order_no锁住一条订单 select t.* from order t where t ...

  9. mysql安全性案例分析_MySQL实例crash的案例分析

    [作者] 王栋:携程技术保障中心数据库专家,对数据库疑难问题的排查和数据库自动化智能化运维工具的开发有强烈的兴趣. [问题描述] 我们生产环境有一组集群的多台MySQL服务器(MySQL 5.6.21 ...

最新文章

  1. java hashmap非线程安全
  2. SpringBoot 集成 thumbnailator (图片缩放,区域裁剪,水印,旋转,保持比例)保姆级教程(含代码)
  3. Java多线程_阻塞队列
  4. 计算机鼠标介绍教学反思,《玩转鼠标》教学反思
  5. 目标检测——域适应的学习笔记
  6. 在 CentOS 上安装 Docker 引擎
  7. 看雪CTF.TSRC 2018 团队赛 第八题 『二向箔』 解题思路
  8. 密度聚类( DBSCAN )
  9. c#程序设计实训报告心得体会_C程序设计实训个人总结(推荐五篇)
  10. AN 非空检测以及影片剪辑元件调用内部元件
  11. ie主页被篡改(修改注册表)
  12. 【R语言】预测模型最合适阈值Cutoff选取及其它指标计算
  13. 抖音怎么知道自己上热门 手机视频md5值修改
  14. 限流Throttling
  15. 【C】 求3个正整数的最小公倍数
  16. 前端工具webpack-打包优化-第1篇
  17. Intel芯片组大全最新版
  18. 《编译 - 编译杂记》GCC优化等级说明
  19. 5款尽情歌唱的免费卡拉OK电脑软件
  20. -XX:+UseCompressedOops 与 -XX:-UseCompressedOops

热门文章

  1. Rwordseg安装
  2. Oracle密码过期及账户解锁的问题
  3. excel文件成绩处理python代码_Python处理Excel文件实例代码
  4. 95-910-330-源码-FlinkSQL-Calcite-Flink结合Calcite
  5. 【MySQL】故障分析 | MySQL 优化案例 - 字符集转换
  6. 95-235-038-源码-task-Task Slot
  7. 【Siddhi】Siddhi 组件架构
  8. Maven: NoSuchMethodError fasterxml.jackson.core强行指定,无法排除
  9. 【安全】CDH集群开启Kerberos安全认证
  10. spark学习-43-Spark的BlockManager