大家好,欢迎回到性能调优培训今天标志着第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. python多线程的用法之一

    import threadingimport time class thread_1(threading.Thread): sleep_time = 0 def __init__(self,id1): ...

  2. 在ASP.NET WebAPI 中使用缓存【Redis】

    初步看了下CacheCow与OutputCache,感觉还是CacheOutput比较符合自己的要求,使用也很简单 PM>Install-Package Strathweb.CacheOutpu ...

  3. [.net 面向对象程序设计进阶] (6) Lamda表达式(二) 表达式树快速入门

    [.net 面向对象程序设计进阶] (6) Lamda表达式(二) 表达式树快速入门 本节导读: 认识表达式树(Expression Tree),学习使用Lambda创建表达式树,解析表达式树. 学习 ...

  4. statcounter统计的浏览器市场占有率

      Source: StatCounter Global Stats - Browser Market Share

  5. jQuery的选择器中的通配符[id^='code']

    1.选择器 (1)通配符: $("input[id^='code']");//id属性以code开始的所有input标签 $("input[id$='code']&quo ...

  6. 知方可补不足~用SqlProfiler来监视数据库死锁

    回到目录 关于锁的相关知识,大家可以看我的这篇文章<知方可补不足~Sqlserver中的几把锁和.net中的事务级别> 死锁我想大家都知道,当一个对话(线程)占用一个资源时,别一个线程也同 ...

  7. yar粗略使用记录

    yar是鸟哥(laruence)开发的一个并行的RPC框架.据说sina weibo已经在大规模使用这个框架了.今天初步使用了下,觉得还是挺爽的一个工具. 什么情况适用这个工具呢? 比如一般你有个微博 ...

  8. poi 输出Excel显示内容

    在业务系统中多少回接触到Excel解析.在java开发平台下选择 Apache POI是一个非常明智的选择,POI提供非常完善API来读取或写入Microsoft Office Excel. 目前对导 ...

  9. Android笔记——探究活动

    1.活动是什么       活动(Activity)是最容易吸引到用户的地方了,它是一种可以包含用户界面的组件,主要用于和用户进行交互.一个应用程序中可以包含零个或多个活动,但不包含任何活动的应用程序 ...

  10. python2.7和python3共存

    python2.7和python3共存 原本装了python,玩nodejs的时候需要node-gyp来编译依赖,无赖这货需要python2.5<v<3.0,那就弄两个版本吧 转载自 ht ...