[翻译]:SQL死锁-锁的类型

时间:2022-09-28 19:33:19

很久没有写博客了,这里面的原因有很多。最近的一个项目由于客户明确提出要做下性能压力测试,使用的工具就是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个格子的表格。但对于我们来讲,只需要关注如下压缩之后的版本即可。

[翻译]:SQL死锁-锁的类型

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

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

其实这个颜色的标注容易让人不理解,还是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. Python开发程序:选课系统-改良版

    程序名称: 选课系统 角色:学校.学员.课程.讲师要求:1. 创建北京.上海 2 所学校2. 创建linux , python , go 3个课程 , linux\py 在北京开, go 在上海开3. ...

  2. [源码解析]HashMap和HashTable的区别(源码分析解读)

    前言: 又是一个大好的周末, 可惜今天起来有点晚, 扒开HashMap和HashTable, 看看他们到底有什么区别吧. 先来一段比较拗口的定义: Hashtable 的实例有两个参数影响其性能:初始 ...

  3. Scalaz(51)- scalaz-stream: 资源使用安全-Resource Safety

    scalaz-stream是一个数据流处理工具库,对资源使用,包括:开启文件.连接网络.连接数据库等这些公共资源使用方面都必须确定使用过程的安全:要保证在作业终止时能进行事后处理程序(finalize ...

  4. 【转】Unity利用WWW http传输Json数据

    http://blog.csdn.net/h570768995/article/details/50386935 首先去下载LitJson.dll,放在Plugins 目录下: LitJson可以从下 ...

  5. hdu 5311 Hidden String (BestCoder 1st Anniversary ($))(深搜)

    http://acm.hdu.edu.cn/showproblem.php?pid=5311 Hidden String Time Limit: 2000/1000 MS (Java/Others)  ...

  6. USB设备架构

    USB设备,分为3层:1.底层为传送和接受数据的总线接口:2.中间层处理总线和不同端点的数据传输:3.最高层由串行总线设备提供.主要研究中间层. USB设备状态,主要研究外部可见状态. 1,连接态-- ...

  7. jquery中的全局事件

    ajaxStart(callback):Ajax请求开始时触发该事件 ajaxSend(callback):Ajax请求发送前触发该事件 ajaxSuccess(callback):Ajax请求成功时 ...

  8. UVA 11582 Colossal Fibonacci Numbers(数学)

    Colossal Fibonacci Numbers 想先说下最近的状态吧,已经考完试了,这个暑假也应该是最后刷题的暑假了,打完今年acm就应该会退了,但是还什么都不会呢? +_+ 所以这个暑假,一定 ...

  9. oracle查看被锁的表和解锁

    --以下几个为相关表SELECT * FROM v$lock;SELECT * FROM v$sqlarea;SELECT * FROM v$session;SELECT * FROM v$proce ...

  10. vue之后台管理系统遇到的几个痛点

    杂七杂八的一些日总结 1.vue(最)合理的处理表单提交和初始化表单数据显示的方式 对于表单处理,繁琐的一个地方就是当出现多个下拉选择的表单框的时候,我们需要进行多次将选择的文本去换对应的id值的操作 ...