大家好,欢迎回到性能调优培训今天标志着第5个月培训的开始,这个月我们会谈论SQL Server里的锁、阻塞和死锁(Locking, Blocking, and Deadlocking)。

SQL Server提供悲观和乐观并发控制模式,它们用来定义并发查询的执行。这期我会给你讲解悲观并发控制模式里各种隔离级别概况,下周我会进一步介绍自SQL Server 2005起引入的乐观隔离级别情况。

悲观隔离级别(Pessimistic Isolation Levels)

悲观隔离级别意味着读查询(SELECT)阻塞写查询(INSERT,UPDATE,DELETE),而且写查询阻塞读查询。SQL Server对此行为使用所谓的锁(Locks)

  • 读操作获取共享锁(Shared Locks (S))
  • 写操作获取排它锁(Exclusive Locks (X))

2个锁之间互不兼容。这就是说不能同时读写一条记录。如果这个发生的话,就会出现所谓的阻塞(Blocking)情形。当你设置指定的事务隔离级别(transaction isolation level)后,你就直接影响读查询在写查询同时进行时如何把持它们的共享锁(S)。你不能影响写操作——当你在表上修改一条记录(INSERT,UPDATE,DELETE)总会拿到排它锁(X)。

默认情况每个查询在提交读(Read committed)隔离级别运行。提交读意味着SQL Server在记录读取时会在记录上获取一个共享锁(S),一旦记录完全读取或处理,共享锁(S)就是立即释放。当你对表进行扫描(Scan)运算符(单线程),在给定时间内只有一个共享锁(S)把持着。因为这个行为,其他事务随后修改记录是可能的。如果你在同个事务里读取同个记录,你应该使用所谓的不可重复读(Non-Repeatable Read):你多次读取一条记录,但却返回不同的值。

如果你不能忍受可重复读的行为,你可以使用限制更多的可重复读(Repeatable Read)。这个隔离级别给你可重复的读(因名而来),即当你读取一条记录时,SQL Server会保持共享锁(S)直到你事务的结束。因此在你读取的事务期间,没有人可以获取排它锁(X)来改变你的记录(因为这个不兼容性,排它锁会向阻塞让步)。这个方法有优点也有缺点:一方面你获得更准确的记录(可重复读),另一方面你会有更多的阻塞发生,因为读操作把持它们的共享锁(S)直到它们事务的结束。你要在并发控制和数据准确性之间权衡。

你还可以通过改变隔离级别为可串行化(Serializable)来进一步限制。使用那个在SQL Server里最有限制的隔离级别——你可以避免所谓的虚影记录(Phantom Records)。当你多次从表获取记录时,虚影记录会出现并消失。为了避免虚影记录,SQL Server使用所谓的Key Range Locking技术,即通过锁定你初次获取的范围数据。

因此没有其它的并发查询可以在锁定范围内插入记录。从范围内删除记录,或“移动”另一条记录到此范围的更新语句都是不可能的。这样的查询只会阻塞。在你行范围定义记录的查询谓语上,你也需要支持的索引。用支持的索引,SQL Server会锁定各个索引键。没有支持的索引,SQL Server就会锁定你的整张表,这会大大伤及你数据库的并发和工作量!

最后SQL Server支持未提交读(Read Uncommitted)隔离级别。使用提交读,当读取数据时,不需要获得共享锁(S)。因此从当前正在进行的事务中读到未提交的数据是可能的。那就是所谓的脏读(Dirty Read)。如果这样的事务回滚,你就读到了数据库里逻辑上不存在的数据。这是个并不推荐的隔离级别,用的时候要慎重考虑下。使用著名的NOLOCK查询提示就可以强制脏读。

悲观隔离级别并不复杂,是不是?隔离级别就是表示对于读取的数据共享锁(S)可以把持多久。基于此,隔离级别就定义了在数据读取期间,哪些是可以操作的,哪些是不能操作的。看下图就会明白。

                脏读(Dirty Read)  不可重复读(Non-Repeatable Read)  虚影记录(Phantom Records)

未提交读(Read Uncommitted)     是          是                  是

提交读(Read Committed)     否          是                  是

重复读(Repeatable Read)     否          否                  是

可序列话(Serializable)        否          否                  否

另外为了保证查询的正确性,对于指定的隔离级别,SQL Server会临时提升隔离级别。你可以围观这个文章:事务隔离级别神话与误解

小结

今天你已经学习了SQL Server里各个悲观隔离级别的基础。当你对SQL Server里的锁和阻塞情况进行故障排除时,这是你必须知道的基础:读查询(SELECT)阻塞写查询(INSERT,UPDATE,DELETE),而且写查询阻塞读查询。

下周我们会谈论SQL Server支持的使用乐观并发控制(Optimistic Concurrency)组合的另外2个隔离级别。请继续关注!

围观PPT:

0914_17a悲观并发控制.rar

0922_17_悲观并发控制.rar

1012_17未提交读、提交读、不可重复读、幻影读(演示).rar

1019_17_可重复读、序列化(演示).rar

1027_17意向锁.rar

第17/24周 悲观并发控制(Pessimistic Concurrency)的更多相关文章

  1. 第18/24周 乐观并发控制(Optimistic Concurrency)

    大家好,欢迎回到性能调优培训.上个星期我通过讨论悲观并发模式拉开了第5个月培训的序幕.今天我们继续,讨论下乐观并发模式(Optimistic Concurrency). 行版本(Row Version ...

  2. 第0/24周 SQL Server 性能调优培训引言

    大家好,这是我在博客园写的第一篇博文,之所以要开这个博客,是我对MS SQL技术学习的一个兴趣记录. 作为计算机专业毕业的人,自己对技术的掌握总是觉得很肤浅,博而不专,到现在我才发现自己的兴趣所在,于 ...

  3. Optimistic Concurrency VS. Pessimistic Concurrency Control

    原创地址:http://www.cnblogs.com/jfzhu/p/4009918.html 转载请注明出处   (一)为什么需要并发控制机制 并发控制机制是为了防止多个用户同时更改同一条数据,也 ...

  4. 第19/24周 锁升级(Lock Escalations)

    大家好,欢迎回到性能调优培训.上2个星期我们已经讨论了SQLServer里的悲观和乐观锁.今天我想谈下SQL Server里对于锁的一个特殊现象:所谓的锁升级(Lock Escalations).在我 ...

  5. 乐观锁(optimistic locking)与悲观锁(pessimistic locking)

    首先,乐观锁(optimistic locking)与悲观锁(pessimistic locking)基本是针对数据处理来说,也就是跟数据库有关的术语,目的是为了解决并发处理时所遇到的相关性能问题,以 ...

  6. 分享Kali Linux 2017年第24周镜像文件

     分享Kali Linux 2017年第24周镜像文件  Kali Linux官方于6月11日发布2017年的第24周镜像.这次维持了11个镜像文件的规模.默认的Gnome桌面的4个镜像,E17.KD ...

  7. 第4/24周 页面限制8060 bytes

    恭喜您!在你面前就只剩下几页了,然后你就可以完成第1个月的SQL Server性能调优培训了.今天我将讲下页的一些限制,还有为什么你会喜欢这些限制,同时也会讨厌这些限制. 正如你在第2周学到的,数据页 ...

  8. 第20/24周 死锁(Deadlocking)

    大家好,欢迎回到性能调优培训.今天讨论SQL Server里的死锁(Deadlocking),第5个月的培训就结束了.当2个查询彼此等待,没有查询可以继续它的工作就会发生死锁.第一步我会概括介绍下SQ ...

  9. 第23/24周 临时数据库(TempDb)

    在今天的性能调优培训里我们讨论下TempDb——SQL Server的公共厕所,在SQL Server里我是这样描述它的.我们的每个人都会经常使用TempDb.有些人直接使用它,有些人不直接使用它.今 ...

随机推荐

  1. 测试了几款 C# 脚本引擎 , Jint , Jurassic , Nlua, ClearScript

    测试类 public class Script_Common { public string read(string filename) { return System.IO.File.ReadAll ...

  2. flume 1.4的介绍及使用示例

    flume 1.4的介绍及使用示例 本文将介绍关于flume 1.4的使用示例,如果还没有安装flume的话可以参考:http://blog.csdn.net/zhu_xun/article/deta ...

  3. DeviceOne 竟然做出来如此复杂的App

    分享来自DeviceOne论坛 此文章分享自DeviceOne的论坛,论坛上的用户分享,下面有二维码扫描,可以进行安装和试用.支持android和ios两个 操作系统. 这个还没做完,目前已经完成了初 ...

  4. java提高篇(十)-----详解匿名内部类

    在java提高篇-----详解内部类中对匿名内部类做了一个简单的介绍,但是内部类还存在很多其他细节问题,所以就衍生出这篇博客.在这篇博客中你可以了解到匿名内部类的使用.匿名内部类要注意的事项.如何初始 ...

  5. 巧用JS内置对象Function

    在做练习的时候也好,做项目的时候也好,我经常会碰到想要的到一个字符串“”里面的东西的这样的需求. 注意,“”里面的东西可以是任何东西[],number等等 于是有了个大神教我一个绝招: 于是世界圆满了 ...

  6. 一天一小段js代码(no.4)

    最近在看网上的前端笔试题,借鉴别人的自己来试一下: 题目: 写一段脚本,实现:当页面上任意一个链接被点击的时候,alert出这个链接在页面上的顺序号,如第一个链接则alert(1), 依次类推. 有一 ...

  7. [ACM_几何] Wall

    http://acm.hust.edu.cn/vjudge/contest/view.action?cid=28417#problem/E 题目大意:依次给n个点围成的一个城堡,在周围建围墙,要求围墙 ...

  8. iOS——Core Animation 知识摘抄(一)

    本文是对http://www.cocoachina.com/ios/20150104/10814.html文章的关键段落的摘抄,有需要的看原文 CALayer和UIView的关系: CALayer类在 ...

  9. iOS ARC模式 内存管理

     1,测试一 ;i<;i++) { NSLog(@"i = %d",i); } 2,测试二 ;i<;i++) { NSLog(@"i = %d",i ...

  10. Redis总结笔记(二):C#连接Redis简单例子

    转载于:http://www.itxuexiwang.com/a/shujukujishu/redis/2016/0216/113.html?1455860686 注:C#在调用Redis是不要使用S ...