Sql Server之旅——终点站 nolock引发的三级事件的一些思考
曾今有件事情让我记忆犹新,那年刚来携程不久,马上就被安排写一个接口,供企鹅公司调用他们员工的差旅信息,然后我就三下五除二的给写好
了,上线之后,大概过了一个月。。。DBA那边报告数据库出现大量锁超时,并且及时根据sql的来源将email发到了我们部门,指出sql读取时间过长,
并且缺少nolock,影响了大量机票订单入库,然后我就拿着sql去生产环境跑了下,22s。。。花擦。。。项目上线时间太久,版本已经不存在了,无法
回滚。。。原本准备撤下接口。。。看了下撤下接口跟加上nolock时间相差不多,最后决定先加上nolock,发布紧急单。。。然后再优化,DBA那边暂
时做手工解锁,发上去后,最后就是损失XXXX订单。。。定级为三级事件。然后就是追责,当然这个责任只能有老大们去承担了,出了这次由我引发的
事件,我得思考了,出了事情对我不见得全是坏事,起码这次会让我铭记如心,想想也搓,来携程之前根本就不会关注要不要给select指定nolock,这其
中也包括自己没遇到过大数据吧,也包括自己的能力有限,只知道有锁这个玩意,细说的话就啥也不知道了,后来才知道携程有个规则,就是很多业务产
线所写的select都必须指定nolock,懂一点的人可能会说nolock可以提升性能,如果你这样说,确实是这样,因为数据库的锁是有96字节开销的,没了
锁,也就没有你在profile中看到accquired和released痉挛了,当你看完我的事件之后,你可能会意识到,性能提升不是最关心的,最关心就是不要出现
死锁,锁等待。。。好了,言归正传,下面我们看看到底在数据库中可以指定多少个锁???
一:到底可以指定多少个锁
这个问题有意思,我们不需要记,只要你装一个SQL Prompt,有了这个神器,你就知道到底有多少个?如下图:
DROP TABLE dbo.Person
CREATE TABLE Person(ID INT IDENTITY,NAME CHAR(4000) DEFAULT 'xxxxx')
INSERT INTO dbo.Person DEFAULT VALUES
go 6

一眼扫下去,还是蛮多的,不过你要注意了,那些所谓的XXXLock才是我们需要关注的,根据上面的图,我们大概把锁分个类。。。
粒度锁:PAGLOCK, TABLOCK, TABLOCKX, ROWLOCK, NOLOCK
模式锁:HOLDLOCK, UPDLOCK, XLOCK
接下来我从粒度锁说起:
1. NOLOCK
都说nolock是无锁模式的,那到底是怎样的无锁呢???到这篇为止,你应该知道,如果不加nolock,我们的表,数据页是附加IS锁的,那接
下来我用profile看下两者有什么区别。
从上图中,你会看到加上nolock之后,object上面附加了Sch-S锁,这个锁叫做“架构稳定锁”,很简单就是sql编译时附加的一把锁,目的就是
防止在编译时,有其他连接修改表结构,而这个锁只与Sch-M锁冲突,与其他锁都兼容,这说明什么?说明其他连接锁住了记录也没关系,我的
nolock不跟他们打交道,这样的话,就可能会读到脏数据,不过没关系,携程的很多业务是容许脏数据的,毕竟比锁等待,死锁要强得多,再说
nolock读到了其他连接未修改或者未提交的数据,这个概率也比较低,就算遇到了也没关系,一般不会招来客诉的,客人或许再刷下页面,数据
或许就正确了,对不对。。。
2.TABLOCK
这个还是比较见名识义的,就是附加在table上的锁,也就是表锁了,很恐怖的。。。下面我举个Update的例子,看看前后对比。


在上面你有没有看到,X锁已经附加到OBJECT上面去了。。。这样的话,其他连接就动不了这个Object了,只能等待。。。
3. PAGLOCK
看了名字你应该也知道,就是附加到页面这个级别的锁,我也举一个Update的例子。
BEGIN TRAN
UPDATE dbo.Person SET NAME='aaaaa' WHERE ID=6 BEGIN TRAN
UPDATE dbo.Person WITH(PAGLOCK) SET NAME='bbbbb' WHERE ID=4


从上面两个图中,你应该可以看到,原来附加到RID上面的U锁,由于PagLock的提升,现在要附加到Page上面了,这个就是所谓的数据页锁。
4.TABLOCKX, ROWLOCK
这两个我就不细说了,TABLOCKX就是直接附加在table上的X锁,你可以通过select看一下。

ROWLOCK的话,默认情况下就是ROWLOCK,比如默认的Update,你会发现RID上被附加的U锁,这个就是行锁。
5.UPDLOCK
这个锁还是蛮有意思的,它就是update锁,如果你select下,它会呈现update的锁痉挛效果。

6. XLOCK
知道了UPDLOCK锁,我想XLOCK你也应该明白了。。。它就是delete锁,即排他锁,我可以让select带上排他锁。

7.HOLDLOCK
最后一个我也没闹明白,据说是让语句在整个事务中持有锁,然后我就用select和update调试一下。
SELECT * FROM dbo.Person(HOLDLOCK)
UPDATE dbo.Person WITH(HOLDLOCK) SET NAME='bbbbb' WHERE ID=4

从图中可以看到,HOLDLOCK不管是在select还是Update中,都是对表持有锁,没心情研究了,明天可以回家了。。。留给大家观察吧。
最后祝大家新年愉快,阖家欢乐,我也终于在年前完成了这个系列,也祝贺祝贺自己。
Sql Server之旅——终点站 nolock引发的三级事件的一些思考的更多相关文章
- [转]了解SQL Server锁争用:NOLOCK 和 ROWLOCK 的秘密_Mr_Indigo的空间
了解SQL Server锁争用:NOLOCK 和 ROWLOCK 的秘密 关系型数据库,如SQL Server,使用锁来避免多用户修改数据时的并发冲突.当一组数据被某个用户锁定时,除非第一个用户结束修 ...
- Sql Server之旅——第五站 确实不得不说的DBCC命令
原文:Sql Server之旅--第五站 确实不得不说的DBCC命令 今天研发中心办年会,晚上就是各自部门聚餐了,我个人喜欢喝干红,在干红中你可以体味到那种酸甜苦辣...人生何尝不是这样呢???正好 ...
- (转)Sql Server之旅——第八站 复合索引和include索引到底有多大区别?
索引和锁,这两个主题对我们开发工程师来说,非常的重要...只有理解了这两个主题,我们才能写出高质量的sql语句,在之前的博客中,我所说的 索引都是单列索引...当然数据库不可能只认单列索引,还有我这篇 ...
- 了解SQL Server锁争用:NOLOCK 和 ROWLOCK 的秘密
关系型数据库,如SQL Server,使用锁来避免多用户修改数据时的并发冲突.当一组数据被某个用户锁定时,除非第一个用户结束修改并释放锁,否则其他用户就无法修改该组数据. 有些数据库,包括SQL Se ...
- SQL Server扩充表字段长度,引发的意外KILLED/ROLLBACK
这一段时间,因为系统升级,新系统产生的数据长度,比原来的数据长度要长,所以说要扩充一下字段长度. ) --修改字段长度sql 在执行的时候,有这样一个情况. 例如Student表的Name字段长度是n ...
- 【故障公告】阿里云 RDS SQL Server 数据库实例 CPU 100% 引发全站故障
非常抱歉,今天 8:48 开始,我们使用的阿里云 RDS SQL Server 数据库实例突然出现 CPU 100% 问题,引发全站故障,由此给您带来麻烦,请您谅解. 发现故障后立即进行主备切换,和 ...
- SQL Server Update 语句使用Nolock 语法
Update talblename set Column='XX' from Table TableName with(nolock) where XXX
- Sql Server之旅——第十二站 sqltext的参数化处理
说到sql的参数化处理,我也是醉了,因为sql引擎真的是一个无比强大的系统,我们平时做系统的时候都会加上缓存,我想如果没有缓存,就不会有什么 大网站能跑的起来,而且大公司一般会在一个东西上做的比较用心 ...
- Sql Server之旅——第十一站 简单说说sqlserver的执行计划
我们知道sql在底层的执行给我们上层人员开了一个窗口,那就是执行计划,有了执行计划之后,我们就清楚了那些烂sql是怎么执行的,这样 就可以方便的找到sql的缺陷和优化点. 一:执行计划生成过程 说到执 ...
随机推荐
- 孙鑫MFC学习笔记3:MFC程序运行过程
1.MFC中WinMain函数的位置在APPMODUL.cpp APPMODUL.cpp中是_tWinMain,其实_tWinMain是一个宏#define _tWinMain WinMain 2.全 ...
- linux 如何改变文件属性与权限
我们知道档案权限对于一个系统的安全重要性,也知道档案的权限对于使用者与群组的相关性, 那如何修改一个档案的属性与权限呢? 我们这里介绍几个常用于群组.拥有者.各种身份的权限的指令.如下所示: chgr ...
- 解决远程连接mysql很慢的方法(mysql_connect 打开连接慢)
http://www.jb51.net/article/27616.htm 有次同事提出开发使用的mysql数据库连接很慢,因为我们的mysql开发数据库是单独一台机器部署的,所以认为可能是网络连 ...
- 大家一起撸代码之——Hibernate各种主键生成策略与配置详解
1.assigned 主键由外部程序负责生成,在 save() 之前必须指定一个.Hibernate不负责维护主键生成.与Hibernate和底层数据库都无关,可以跨数据库.在存储对象前,必须要使用主 ...
- jQuery als.js 跑马灯
ali.js是一款滚动插件,滚动的内容可包含文字和图片.它的API也很强大,包括滚动区域可见个数.每次滚动个数.滚动方向.是否循环滚动.是否自动滚动.滚动间隔时间.滚动动画速度.动画效果.滚动方向以及 ...
- 15款免费的响应式 WordPress 主题下载
响应式设计主题最适合杂志网站,博客网站,想要在自己网站上展示自己作品的用户.支持视网膜显示使其在 iPad,iPhone,Mackbook,iMac 等设备上有更高的分辨率. 响应式和现代设计风格的多 ...
- 【web前端面试题整理06】成都第一弹,邂逅聚美优品
前言 上周四回了成都,休息了一下下,工作问题还是需要解决的,于是今天去面试了一下,现在面试回来了,我感觉还是可以整理一下心得. 这个面试题整理系列是为了以后前端方面的兄弟面试时候可以得到一点点帮助,因 ...
- 原生JS:String对象详解
@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/c ...
- npm 安装 ionic cordova
针对npm安装 ionic 和 cordova 过程很慢,且有些安装文件被墙的问题,使用如下方式解决: 1)安装cnpm npm install -g cnpm 2)然后再使用cnpm 安装 ioni ...
- SharePoint 2013 列表关于大数据的测试
本文主要介绍SharePoint列表库的效率问题,一直以来以为阙值5k,超过会线性下降,需要分文件夹存放:或许这是之前版本的描述,但是2013版本通过测试,真心不是这么一回事儿. 下面,简单介绍下自己 ...