第17/24周 悲观并发控制(Pessimistic Concurrency)
2015-07-23 16:40
134 查看
大家好,欢迎回到性能调优培训。今天标志着第5个月培训的开始,这个月我们会谈论SQL Server里的锁、阻塞和死锁(Locking, Blocking, and Deadlocking)。
SQL Server提供悲观和乐观并发控制模式,它们用来定义并发查询的执行。这期我会给你讲解悲观并发控制模式里各种隔离级别概况,下周我会进一步介绍自SQL Server 2005起引入的乐观隔离级别情况。
读操作获取共享锁(Shared Locks (S))
写操作获取排它锁(Exclusive Locks (X))
2个锁之间互不兼容。这就是说不能同时读写一条记录。如果这个发生的话,就会出现所谓的[b]阻塞(Blocking)[/b]情形。当你设置指定的事务隔离级别(transaction isolation level)后,你就直接影响读查询在写查询同时进行时如何把持它们的共享锁(S)。你不能影响写操作——当你在表上修改一条记录(INSERT,UPDATE,DELETE)总会拿到排它锁(X)。
默认情况每个查询在[b]提交读(Read committed)[/b]隔离级别运行。提交读意味着SQL Server在记录读取时会在记录上获取一个共享锁(S),一旦记录完全读取或处理,共享锁(S)就是立即释放。当你对表进行扫描(Scan)运算符(单线程),在给定时间内只有一个共享锁(S)把持着。因为这个行为,其他事务随后修改记录是可能的。如果你在同个事务里读取同个记录,你应该使用所谓的[b]不可重复读(Non-Repeatable Read)[/b]:你多次读取一条记录,但却返回不同的值。
如果你不能忍受可重复读的行为,你可以使用限制更多的[b]可重复读(Repeatable Read)[/b]。这个隔离级别给你可重复的读(因名而来),即当你读取一条记录时,SQL Server会保持共享锁(S)直到你事务的结束。因此在你读取的事务期间,没有人可以获取排它锁(X)来改变你的记录(因为这个不兼容性,排它锁会向阻塞让步)。这个方法有优点也有缺点:一方面你获得更准确的记录(可重复读),另一方面你会有更多的阻塞发生,因为读操作把持它们的共享锁(S)直到它们事务的结束。你要在并发控制和数据准确性之间权衡。
你还可以通过改变隔离级别为[b]可串行化(Serializable)[/b]来进一步限制。使用那个在SQL Server里最有限制的隔离级别——你可以避免所谓的[b]虚影记录(Phantom Records)[/b]。当你多次从表获取记录时,虚影记录会出现并消失。为了避免虚影记录,SQL Server使用所谓的[b]Key Range Locking[/b]技术,即通过锁定你初次获取的范围数据。
因此没有其它的并发查询可以在锁定范围内插入记录。从范围内删除记录,或“移动”另一条记录到此范围的更新语句都是不可能的。这样的查询只会阻塞。在你行范围定义记录的查询谓语上,你也需要支持的索引。用支持的索引,SQL Server会锁定各个索引键。没有支持的索引,SQL Server就会锁定你的整张表,这会大大伤及你数据库的并发和工作量!
最后SQL Server支持[b]未提交读(Read Uncommitted)[/b]隔离级别。使用提交读,当读取数据时,不需要获得共享锁(S)。因此从当前正在进行的事务中读到未提交的数据是可能的。那就是所谓的[b]脏读(Dirty Read)[/b]。如果这样的事务回滚,你就读到了数据库里逻辑上不存在的数据。这是个并不推荐的隔离级别,用的时候要慎重考虑下。使用著名的[b]NOLOCK[/b]查询提示就可以强制脏读。
悲观隔离级别并不复杂,是不是?隔离级别就是表示对于读取的数据共享锁(S)可以把持多久。基于此,隔离级别就定义了在数据读取期间,哪些是可以操作的,哪些是不能操作的。看下图就会明白。
脏读(Dirty Read) 不可重复读(Non-Repeatable Read) 虚影记录(Phantom Records)
未提交读(Read Uncommitted) 是 是 是
提交读(Read Committed) 否 是 是
重复读(Repeatable Read) 否 否 是
可序列话(Serializable) 否 否 否
另外为了保证查询的正确性,对于指定的隔离级别,SQL Server会临时提升隔离级别。你可以围观这个文章:事务隔离级别神话与误解。
下周我们会谈论SQL Server支持的使用乐观并发控制(Optimistic Concurrency)组合的另外2个隔离级别。请继续关注!
0922_17_悲观并发控制.rar
1012_17未提交读、提交读、不可重复读、幻影读(演示).rar
1019_17_可重复读、序列化(演示).rar
1027_17意向锁.rar
SQL Server提供悲观和乐观并发控制模式,它们用来定义并发查询的执行。这期我会给你讲解悲观并发控制模式里各种隔离级别概况,下周我会进一步介绍自SQL Server 2005起引入的乐观隔离级别情况。
悲观隔离级别(Pessimistic Isolation Levels)
悲观隔离级别意味着读查询(SELECT)阻塞写查询(INSERT,UPDATE,DELETE),而且写查询阻塞读查询。SQL Server对此行为使用所谓的[b]锁(Locks)[/b]:读操作获取共享锁(Shared Locks (S))
写操作获取排它锁(Exclusive Locks (X))
2个锁之间互不兼容。这就是说不能同时读写一条记录。如果这个发生的话,就会出现所谓的[b]阻塞(Blocking)[/b]情形。当你设置指定的事务隔离级别(transaction isolation level)后,你就直接影响读查询在写查询同时进行时如何把持它们的共享锁(S)。你不能影响写操作——当你在表上修改一条记录(INSERT,UPDATE,DELETE)总会拿到排它锁(X)。
默认情况每个查询在[b]提交读(Read committed)[/b]隔离级别运行。提交读意味着SQL Server在记录读取时会在记录上获取一个共享锁(S),一旦记录完全读取或处理,共享锁(S)就是立即释放。当你对表进行扫描(Scan)运算符(单线程),在给定时间内只有一个共享锁(S)把持着。因为这个行为,其他事务随后修改记录是可能的。如果你在同个事务里读取同个记录,你应该使用所谓的[b]不可重复读(Non-Repeatable Read)[/b]:你多次读取一条记录,但却返回不同的值。
如果你不能忍受可重复读的行为,你可以使用限制更多的[b]可重复读(Repeatable Read)[/b]。这个隔离级别给你可重复的读(因名而来),即当你读取一条记录时,SQL Server会保持共享锁(S)直到你事务的结束。因此在你读取的事务期间,没有人可以获取排它锁(X)来改变你的记录(因为这个不兼容性,排它锁会向阻塞让步)。这个方法有优点也有缺点:一方面你获得更准确的记录(可重复读),另一方面你会有更多的阻塞发生,因为读操作把持它们的共享锁(S)直到它们事务的结束。你要在并发控制和数据准确性之间权衡。
你还可以通过改变隔离级别为[b]可串行化(Serializable)[/b]来进一步限制。使用那个在SQL Server里最有限制的隔离级别——你可以避免所谓的[b]虚影记录(Phantom Records)[/b]。当你多次从表获取记录时,虚影记录会出现并消失。为了避免虚影记录,SQL Server使用所谓的[b]Key Range Locking[/b]技术,即通过锁定你初次获取的范围数据。
因此没有其它的并发查询可以在锁定范围内插入记录。从范围内删除记录,或“移动”另一条记录到此范围的更新语句都是不可能的。这样的查询只会阻塞。在你行范围定义记录的查询谓语上,你也需要支持的索引。用支持的索引,SQL Server会锁定各个索引键。没有支持的索引,SQL Server就会锁定你的整张表,这会大大伤及你数据库的并发和工作量!
最后SQL Server支持[b]未提交读(Read Uncommitted)[/b]隔离级别。使用提交读,当读取数据时,不需要获得共享锁(S)。因此从当前正在进行的事务中读到未提交的数据是可能的。那就是所谓的[b]脏读(Dirty Read)[/b]。如果这样的事务回滚,你就读到了数据库里逻辑上不存在的数据。这是个并不推荐的隔离级别,用的时候要慎重考虑下。使用著名的[b]NOLOCK[/b]查询提示就可以强制脏读。
悲观隔离级别并不复杂,是不是?隔离级别就是表示对于读取的数据共享锁(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悲观并发控制.rar0922_17_悲观并发控制.rar
1012_17未提交读、提交读、不可重复读、幻影读(演示).rar
1019_17_可重复读、序列化(演示).rar
1027_17意向锁.rar
相关文章推荐
- Canvas createLinearGradient API
- web前端 c标签的使用之<c:forEach>和<c:if test="">
- 使用OpenMP并行处理图像产生冲突的问题
- MySQL的随机数函数rand()的使用技巧
- 最大流之预流推进
- 【异常】R语言使用library("XLConnect"):计算机丢失jvm.dll
- Android 抽屉效果的导航菜单实现
- decorator & generator & iterator
- 龙之森林项目进程
- 浅谈android应用性能之内存(转)
- CentOS 6+Hadoop 2.6.0分布式集群安装
- BaseActivity框架搭建
- 解析XML文件的两种方法
- HDU 2026 首字母变大写
- Maven--要点笔记
- MySQL Study之--MySQL schema_information数据库
- 推荐Eclipse插件:Eclipse Color Theme
- linux Centos iptables 8080
- Linux下配置MySQL需要注意的几点
- C#中流,字节,字符,字符串