大家好,欢迎回到性能调优培训。今天标志着第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. Redis中Value使用hash类型的效率是普通String的两倍

    什么Redis? 点击这里 最近要开发的一个项目是分布式缓存组件,解决参数缓存高效获取的问题.参数达到了500万级别,刚刚开始了解Redis.做设计的时候考虑到Value使用哪种类型的问题? 主要面临 ...

  2. TypeScript之基本数据类型

    前言 最近项目很急,所以没有什么时间回答关于Xamarin.Android方面的问题,也有一段时间没有更新.主要是手头很缺人,如果有谁有兴趣加入我们的话,可以私聊我,这样我就能继续造福社区了,同时还有 ...

  3. 用JQ仿造百度书籍预售页面的单屏滚页效果

    今天的项目需要做到一个介绍页面,我主动提出走单屏滚页的风格,毕竟交互性好,逼格也高,具体效果可以参照百度知道书籍预售页面. 其实现效果就大概是这样的: 还是老样子,所有步骤文件可以从我的Github上 ...

  4. 作业七:团队项目——Alpha版本冲刺阶段-10

    部分代码: public void run(){ while (true){ //单击棋子第一下开始闪烁 if (chessManClick){ play[Man].setVisible(false) ...

  5. 【译】Activitys, Threads和 内存泄露

    Android编程中一个共同的困难就是协调Activity的生命周期和长时间运行的任务(task),并且要避免可能的内存泄露.思考下面Activity的代码,在它启动的时候开启一个线程并循环执行任务. ...

  6. Linux gzip、gunzip

    200 ? "200px" : this.width)!important;} --> 介绍 gzip是linux自带的压缩文件命令,它的压缩比大概能达到60%-70%,比z ...

  7. SmartImageView

    == public class SmartImageView extends ImageView { public SmartImageView(Context context) { super(co ...

  8. C#入门基础三

    封装:简化用户接口,隐藏实现细节. get{return 属性值:} set{属性值 = value:} 继承:子类继承父类所有非私有成员.继承具有传递性,单根性. 隐式继承:用引号(:)实现. 显示 ...

  9. List.Foreach与C#的foreach的区别

    几年前参加面试时就被提问过,现在面试别人时也经常提到这个问题. 今天小试了一下.得出如下几点: 1. 首先,mscorlib里System.Collections.Generic. List<T ...

  10. Javascript中构造函数与new命令2

    典型的面向对象编程语言(比如C++和Java),存在"类"(class)这个概念.所谓"类"就是对象的模板,对象就是"类"的实例.但是,在J ...