很久没有写博客了,这里面的原因有很多。最近的一个项目由于客户明确提出要做下性能压力测试,使用的工具就是VS自带的压力测试工具。以前其它项目做压力测试后反馈的其中一个重要问题就是数据库的死锁。没想到我们这个项目测试时死锁同样的发生了,我之前的项目由于很少参与压力测试,基本上也不会去了解死锁,以及死锁如何解决的问题。

既然有了这个需求,那么要想解决死锁就需要对死锁的相关知识有一定的了解,对于非DBA的来讲并不需要了解的特别深,知道基本概念以及常见分析方法即可,毕竟我们不靠这个吃饭,没必要达到特别细的境界。于时我找到了这一系列的文章,加上我的理解特此翻译过来加深印象。

注:我的英文并不是特别好,且我不会严格按原文的逻辑顺序来翻译,会加入一些自己的理解,所以为了不让其它让被我的翻译误解,会有原文对照。

One of the most challenging issues for developers who don’t live in RDBMS world is how to make the system working seamlessly in multi-user environment. The code which works perfectly in development and QA starts to fall apart when dozens of users access the system. There are timeouts, deadlocks and other issues that developer cannot even reproduce in house. It does not really matter that SQL Server uses row level locking, that transaction isolation level set to read uncommitted – locking, blocking and deadlocking still occurs.

对于程序员来讲最大的挑战之一就是能够确保开发的系统在多人使用时也能无缝的工作。有的时候开发堪称完美的代码当出现多人访问系统时会出现系统崩溃的情况,这其中的原因有超时,死锁或者是其它一些我们意想不到的原因。尽管SQL SERVER是行锁定,也可以设置事务级别来读取未提交的数据,但死锁,阻塞的问题仍然会发生。

Today I’m going to start the series of the posts about locking in Microsoft SQL Server. I’ll try to explain why blocking and deadlocks occur in the system, how you can troubleshoot related problems and what should you do in order to minimize it. We will cover different transaction isolation levels and see how and why it affects behavior of the system. And talk about quite a few other things.

今天我将开始写一系列关于SQL SERVER锁的文章,我会解释为什么阻塞以及死锁会出现在系统中,以及你怎样去排除解决这些问题,如何将问题的影响降到最低。我们会通过修改不同的事务级别来看是如何影响系统行为的,同时我也会谈一些其它相关的内容。

So let’s start with the lock types. What is the lock? In short, this is in-memory structure (64 bytes on 32 bit OS or 128 bytes on 64 bit OS). The structure has the owner, type and resource hash that links it to the resource it protects (row, page, table, file, database, etc). Obviously it’s more complicated and has quite a few other attributes, but for our practical purposes that level of details is enough.

所以我们首先要了解了锁的类型。什么是锁呢?简单来讲,它是一种内存结构(32位操作系统中占64字节,或者64位操作系统占128字节),从保护级别来看,分行锁,页锁,表锁,数据库锁等等。

注:这段我并未深入理解,所以精简了一些。

SQL Server has more than 20 different lock types but for now let’s focus on the most important ones.

SQL SERVER 有20多种不同的锁,但我们只需要关注几种重要的即可。

  • Shared locks (S). Those locks acquired by readers during read operations such as SELECT. I’d like to mention that it happens in most part of the cases but not all the time. There are some cases when readers don’t acquire (S) locks. We will talk about it later.

共享锁(S),这些锁一般出现在我们使用了select语句查询时,我想提醒的是,并不是所有的select查询都会有共享锁,有些情况是不需要共享锁的,我们后续再讲。

  • Exclusive locks (X). Those locks acquired by writers during data modification operators such as Insert, Update or Delete. Those locks prevent one object to be modified by the different sessions. Those locks are always acquired and held till end of transaction

排它锁(X),这些锁一般出现在往数据表写入数据,比如插入数据,更新数据以及删除数据。排它锁保证同一时间只有一个会话能够对数据进行写入操作至于写入的事务结束。

  • Update locks (U). Those locks are the mix between shared and exclusive locks. SQL Server uses them with data modification statements while searching for the rows need to be modified. For example, if you issue the statement like: “update MyTable set Column1 = 0 where Column1 is null” SQL Server acquires update lock for every row it processes while searching for Column1 is null. When eligible row found, SQL Server converts (U) lock to (X).

更新锁(U),这些锁界于共享锁以及排它锁之间。SQL SERVER在调用update语句时先要搜索出哪些数据行是需要更新的。比如我们查询:“update MyTable set Column1=0 where Colum1 is null” SQL SERVER会申请更新锁去查询数据表的每一行是否是符合更新条件的(Column is null)。一旦找到需要更新的数据行,SQL SERVER会将更新锁升级成排它锁。

  • Intent locks (IS, IX, IU, etc). Those locks indicate locks on the child objects. For example, if row has (X) lock, it would introduce (IX) locks on page, table and database level. Main purpose of those locks is optimization. This about situation when you need to have exclusive access to the database (i.e. (X) lock on database level). If SQL Server did not have intent locks, it would have to scan all rows in the all objects and see if there are any low level locks acquired.

意向锁(IS,IX,IU,等等)。这些锁表明它的子对象中有级别更高的锁。比如如何一个数据行上有X锁,会在这个行数据所处的数据页,表,数据库级别上存在IX的锁。这样设计的主要目的是为了优化。当你需要以独占方式去访问数据库时(如果此时X锁设置在数据库级别上),它会遍历所有对象中的所有行,来判断是否有比X锁低的锁存在。

注:这个我理解的不是很好,可能是SQL SERVER在获取锁的机制遵循由低到高的原则,即要想获得级别高的锁先要获取级别低的锁,从而降低同一资源的相互竞争。

Obviously the biggest question is lock compatibility. If you open MSDN site you’ll see nice and “easy to understand” matrix with more than 400 cells. But for our practical purpose let’s focus on the smaller version:

很明显,最大的问题就是这些锁之间的兼容性问题。如果你打开MSDN site 你将会看到更加详细的内容,包含一个超过400个格子的表格。但对于我们来讲,只需要关注如下压缩之后的版本即可。

注:刚开始看的时候,我对作者标注的颜色代表的含义也不太清楚,看了他后面的说明我大致理解了下,具体如下:

    • 绿色:代表完全兼容,不会发生阻塞以及死锁
    • 黄色:代表在特定情况下会出现不兼容的情况
    • 红色:最容易造成死锁

其实这个颜色的标注容易让人不理解,还是MSDN上的无着色的表格会好比较单纯点:

兼容模式

锁请求模式

IS

S

U

IX

SIX

X

Intent shared (IS)

Yes

Yes

Yes

Yes

Yes

No

Shared (S)

Yes

Yes

Yes

No

No

No

Update (U)

Yes

Yes

No

No

No

No

Intent exclusive (IX)

Yes

No

No

Yes

No

No

Shared with intent exclusive (SIX)

Yes

No

No

No

No

No

Exclusive (X)

No

No

No

No

No

No

 

So what we need to remember are basically 3 things:

从这张表格中可以得出下面三个关注:

  1. (S) locks are compatible with (S) and (U) locks.

共享锁和共享锁以及更新锁是兼容

  1. (X) locks are incompatible with any other lock types

排它所和任何锁都不兼容

  1. (U) locks are compatible with (S) but incompatible with (U)

更新锁和共享锁之间是兼容的,但更新锁与更新锁之间是不兼容的

Simple enough. Next time we will look at transaction isolation levels and see how it affects lock behavior.

下一次我们会讲事务级别是如何影响锁行为的。

原文地址如下:

[翻译]:SQL死锁-锁的类型的更多相关文章

  1. [翻译]:SQL死锁-锁与事务级别

    其实这一篇呢与解决我项目中遇到的问题也是必不可少的.上一篇讲到了各种锁之间的兼容性,里面有一项就是共享锁会引起死锁,如何避免呢,将我们的查询都设置中read uncommitted是否可行呢?其结果显 ...

  2. [翻译]:SQL死锁-死锁排除

    As we already saw, the reasons why we have blocking issues and deadlocks in the system are pretty mu ...

  3. [翻译]:SQL死锁-阻塞

    一般情况下死锁不是一步到位的,它必须满足特定的条件,然后形成资源的循环依赖才会产生死锁,死锁之前一定会出现阻塞,由阻塞升级才有可能出现死锁,所以我们有必要了解系统中都有哪些已经被阻塞的锁. 我在解决共 ...

  4. [翻译]:SQL死锁-阻塞探测

    到了这篇,才是真正动手解决问题的时候,有了死锁之后就要分析死锁的原因,具体就是需要定位到具体的SQL语句上.那么如何发现产生死锁的问题本质呢?下面这篇讲的非常细了,还提到了不少实用的SQL,但对我个人 ...

  5. [翻译]:SQL死锁-为什么会出现死锁

    下面这篇对理解死锁非常重要,首先死锁是如何产生的我们要清楚. We already know why blocking occurs in the system and howto detect an ...

  6. SQL死锁知识及解决办法

    [翻译]:SQL死锁-死锁排除 min.jiang 2014-03-18 00:23 阅读:874 评论:1     项目中死锁的解决经历 min.jiang 2014-03-17 01:09 阅读: ...

  7. SQL Server锁类型

    SQL Server锁类型(SQL)收藏 1. HOLDLOCK: 在该表上保持共享锁,直到整个事务结束,而不是在语句执行完立即释放所添加的锁. 2. NOLOCK:不添加共享锁和排它锁,当这个选项生 ...

  8. MySQL的死锁系列- 锁的类型以及加锁原理

    疫情期间在家工作时,同事使用了 insert into on duplicate key update 语句进行插入去重,但是在测试过程中发现了死锁现象: ERROR 1213 (40001): De ...

  9. 为什么说JAVA中要慎重使用继承 C# 语言历史版本特性(C# 1.0到C# 8.0汇总) SQL Server事务 事务日志 SQL Server 锁详解 软件架构之 23种设计模式 Oracle与Sqlserver:Order by NULL值介绍 asp.net MVC漏油配置总结

    为什么说JAVA中要慎重使用继承   这篇文章的主题并非鼓励不使用继承,而是仅从使用继承带来的问题出发,讨论继承机制不太好的地方,从而在使用时慎重选择,避开可能遇到的坑. JAVA中使用到继承就会有两 ...

随机推荐

  1. [leetcode]Excel Sheet Column Number

    26进制 class Solution { public: int titleToNumber(string s) { ; ; i < s.size(); i++) { n = n * + s[ ...

  2. 微信、qq时间格式模板

    产品近来蛋疼,时间格式从做完到现在改了四遍了 ,最新的要求如下: * 2分钟内 无显示 * 2分钟-24小时 HH:mm * 昨天 昨天 HH:mm * 前天 前天 HH:mm * 今年 MM:DD ...

  3. HTML CSS——margin和padding的学习

    你在学习margin和padding的时候是不是懵了,——什么他娘的内边距,什么他娘的外边距.呵呵呵,刚开始我也有点不理解,后来通过查资料学习总算弄明白了,现在我来谈一下自己对margin和paddi ...

  4. c# socket 框架学习 SocketAsyncEventArgsPool 封装

    public class SocketAsyncEventArgsPool{ //已使用记录 private List<Int32> usedRecord; //未使用记录 private ...

  5. Heavy Transportation(最短路 + dp)

    Heavy Transportation Time Limit:3000MS     Memory Limit:30000KB     64bit IO Format:%I64d & %I64 ...

  6. zmq 学习笔记

    0. PUB/SUB, XPUB/XSUB filtering happens at publisher sides when sockets are using a connected protoc ...

  7. centos下配置java环境变量

    一. 需要配置的环境变量1. PATH环境变量.作用是指定命令搜索路径,在shell下面执行命令时,它会到PATH变量所指定的路径中查找看是否能找到相应的命令程序.我们需要把 jdk安装目录下的bin ...

  8. MFC设置静态文本框,编辑框等控件背景和字体颜色

    在MFC类库提供了CWnd::OnCtlColor函数,在工作框架的子窗口被重画时将调用该成员函数.因此可以重载WM_CTLCOLOR消息的响应函数.此函数的原型:afx_msg HBRUSH OnC ...

  9. 我所研究过的 ASP.NET MVC 或者 .NET 或者 ORM 或者框架的开源项目

    ASP.NET MVC 的开源项目有很多,这里列出我所研究过的: SocialGoal v1.0.0 prodinner nopCommerce SmartStore.NET 由于今天才做收集工作,可 ...

  10. ionic 添加应用图标与启动页

    由于手机有很多不同的尺寸与版本,所以图标尺寸也是大小不一,但是如果手动每一个尺寸都制作一个图标,那估计美工会吐血吧,不过幸好,ionic只需要一个图标就可以制作不同尺寸的图标. 添加一个ionic项目 ...