悲观并发控制(Pessimistic Concurrency)
悲观隔离级别(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),而且写查询阻塞读查询。
本文转自Woodytu博客园博客,原文链接:http://www.cnblogs.com/woodytu/p/4669721.html,如需转载请自行联系原作者
悲观并发控制(Pessimistic Concurrency)相关推荐
- ADO.NET - Optimistic Pessimistic Concurrency
Optimistic currency failed, http://msdn.microsoft.com/en-us/library/aa0416cz.aspx 转载于:https://www.cn ...
- NHibernate之旅(7):初探NHibernate中的并发控制
本节内容 什么是并发控制? 悲观并发控制(Pessimistic Concurrency) 乐观并发控制(Optimistic Concurrency) NHibernate支持乐观并发控制 实例分析 ...
- 狂胜——Redis学习笔记
[狂神说Java]Redis最新超详细版教程通俗易懂_哔哩哔哩_bilibili 总体大纲outline nosql讲解,非关系型数据库 阿里巴巴架构演进 nosql数据模型 Nosql四大分类 CA ...
- 狂神redis课程笔记
Redis 文章目录 Redis Nosql 单机SQL时代,更多使用静态网页 Memcached缓存+MySQL+垂直拆分(读写分离) 分库分表+水平拆分+M有SQL集群 最近的年代 最后总结为什么 ...
- lock是悲观锁还是乐观锁_图文并茂的带你彻底理解悲观锁与乐观锁
点击上方蓝色字体,选择"设置星标" 优质文章,第一时间送达 文章转自:Hollis 原创:安静的boy 这是一篇介绍悲观锁和乐观锁的入门文章.旨在让那些不了解悲观锁和乐观锁的小白们 ...
- 计算机专业术语对照表_艾孜尔江编
A abstraction layer,抽象层 access,获取,存取 acoustic coupler,声音耦合器 Active Directory,活动目录 Acyclic Dependenci ...
- Java开发技巧——并发控制中的乐观锁与悲观锁
1.为什么需要锁? 在多用户环境中,在同一时间可能会有多个用户新相同的记录,这会产生冲突.这就是的并发性问题. 2.典型的冲突类型: (1)丢失新:一个事务的新覆盖了其它事务的新结果,就是所谓的新丢失 ...
- 并发控制中的乐观锁与悲观锁
为什么需要锁(并发控制)? 在多用户环境中,在同一时间可能会有多个用户更新相同的记录,这会产生冲突.这就是著名的并发性问题. 典型的冲突有: (1)丢失更新:一个事务的更新覆盖了其它事务的更新结果,就 ...
- 数据库并发控制,选择乐观锁还是悲观锁?
出处:http://www.cnblogs.com/chenlulouis/ 今天,在这里,我们将讨论的是在实际生产过程中,对于并发控制你是选择乐观锁还是悲观锁.这两种锁各自的应用环境应该怎样选择? ...
- 并发控制常见手段-----乐观锁和悲观锁
原文出处:http://blog.csdn.net/hongchangfirst/article/details/26004335 悲观锁(Pessimistic Lock), 顾名思义,就是很悲观, ...
最新文章
- stm32怎么用keil软件进行仿真?(必需掌握的技能)
- NodeJS:将指定文件夹内所有文件重命名为英文
- angular js一factory,service,provider创建服务
- dummy.php 下载,internal dummy connection
- Linux watch 监控系统状态
- 多线程(6)线程同步
- linux搭建lnnp_linux主机安装lnmp详细步骤
- C语言项目:绽放的玫瑰花
- java商城_java网上商城系统怎么样?优势又有哪些?
- Oracle 表空间常用sql
- 【HTML+CSS网页设计与布局 从入门到精通】第11章-CSS
- 双向关联一对一映射详解(1)
- ORACLE 登录相关的信息
- Vc2013实战(1) 别无选择的Mfc
- SQL2000置疑数据库修复
- 【洛谷试炼场】普及练习场——排序
- 关于导入百度导航SDK报错以及解决方案
- CSP模测(一)A卷
- 母版页的详细使用介绍
- 【妙python】按照元素长度排序列表
热门文章
- “三权分立”模型之角色模型
- 正则表达式网站在线测试
- 系统内存占用率高导致电脑卡顿的解决方案
- 洛谷P1867 【Mc生存】经验值
- pyspark LEAK: ByteBuf.release() was not called before it's garbage-collected. Enable advanced leak
- 商用字体网站,再也不用怕侵权
- 1.机器学习入门-初学者的机器学习
- 如何优雅地删除Redis大键
- 某云盘下载工具(IDM,Aria2)速度测试
- 格拉姆-施密特正交化