SQL SERVER的锁机制(四)——概述(各种事务隔离级别发生的影响)
六、各种事务隔离级别发生的影响
修改数据的用户会影响同时读取或修改相同数据的其他用户。即这些用户可以并发访问数据。如果数据存储系统没有并发控制,则用户可能会看到以下负面影响:
· 未提交的依赖关系(脏读)
· 不一致的分析(不可重复读)
· 幻读
(一)脏读:
例:张某正在执行某项业务,如下:

begin tran insert tbUnRead select 3,'张三' union select 4,'李四' ---延迟秒,模拟真实交易情形,用于处理业务逻辑 waitfor delay '00:00:05' rollback tran ---此时李某对表中数据进行查询,执行了以下语句: set Transaction isolation level read uncommitted --查询数据 select * from tbUnRead where name like '张%'

则李某可以看到张某所执行的插入语句,把数据添加到了数据库,如下图。

但是张某最终是没有提交事务,而是回滚了事务,所以这条记录并没有真正插入到数据库中。从而发生李某将脏读的数据当成真实的查询结果。
要解决此问题,就是要把数据库的事务隔离级别由未提交读修改成已提交读。只有当查询结果的正确性不是非常重要,或者是隔一段时间查询一次情况下,即使这一次查询结果是错,而下次查询结果是对的,并不会有太大影响,这才适合使用未提交读。
(二)不可重复读
例:张某正在查询数据,如下

set Transaction isolation level read committed begin tran select * from tbUnRead where ID=2 ---延迟秒,模拟真实交易情形,用于处理业务逻辑 waitfor delay '00:00:05' select * from tbUnRead where ID=2 commit tran ---此时李对表中数据进行了更新,如下语句: update tbUnRead set name='Jack_upd' where ID=2

上面的执行语句造成张某在同一个事务内,两次相同的查询条件,查询到不相同的结果(如下图)。

这是由于“已提交读”隔离级别对共享锁保留的时间是:一旦查询完毕就立即释放,而非事务完成才释放。所在张某虽然还在使用事务,事务过程中的所有独占锁都会一直保留,让事务中所更改的数据别人不可进行查询与更改,直到事务完成。但是,被查询的数据在事务过程中是查询完毕就立即释放共享锁,所以别人仍然可以进行修改,造成一笔事务中,两次相同的查询条件,可以得到不相同的结果。最佳的解决方案是将隔离级别设置为“可重复读”。
“可重复读”事务隔离级别,让事务过程中所曾经建立的共享锁都一直保留到事务完成,虽然可以避免“不可重复读”的问题,但是也会导致数据锁定太久,而别人无法读取数据,影响并发率,甚至提高了“死锁”的发生率。
(三)幻读
例:张某正在查询数据,如下

set Transaction isolation level REPEATABLE READ begin tran select * from tbUnRead where ID=3 ---延迟秒,模拟真实交易情形,用于处理业务逻辑 waitfor delay '00:00:05' select * from tbUnRead where ID=3 commit tran --此时李某新增了一条记录,如下语句: INSERT TBUNread select 3,'幻读'

张某已经把隔离级别设置为“可重复读”,虽然是曾经读取的数据,不管是共享锁还是互斥锁都 保留到了事务结束,但是无法阻止其他人运行新增操作,导致第一次查询时没有数据,第二次查询时却有了数据。被称为“幻读”。如下图。

为了避免此类问题,可以将隔离级别设置为“可序列化”,设置之后,则其他人则无法新增数据。
七、各隔离级别所能防止的访问错误
|
隔离级别 |
脏读 |
不可重复读 |
幻读 |
|
未提交读 |
是 |
是 |
是 |
|
已提交读 |
否 |
是 |
是 |
|
可重复读 |
否 |
否 |
是 |
|
快照 |
否 |
否 |
否 |
|
可序列化 |
否 |
否 |
否 |
八、常用锁与事务隔离级别间的交互影响
|
已提交读 |
可重复读 |
快照 |
可序列化 |
|
|
共享 |
读完数据后就释放 |
事务结束才释放 |
不加锁,以版本来控制 |
事务结束才释放 |
|
更新 |
读完数据后就释放或是升级成独占锁 |
读完数据后就释放或是升级成独占锁 |
不加锁,以版本来控制 |
读完数据后就释放或升级成独占锁 |
|
独占 |
事务结束才释放 |
事务结束才释放 |
不加锁,以版本来控制 |
事务结束才释放 |
九、动态锁定管理
数据库引擎使用动态锁定管理策略来控制锁定和系统的最佳成本效益。数据库引擎可以动态调整数据粒度与锁定类型,当使用最低一级的行锁而非更大范围的页锁时,可以降低两个事务要求相同范围的数据锁定的可能性,增强并行访问的能力,可同时服务更多的用户,减小死锁的机率。相反低级锁转为高级锁可以减小系统的资源负担,但会增加并行争用的可能性。
此机制由锁管理器进行管理,每一个锁都需要内存去记录,并且要与锁管理器进行合作,才能完成数据访问操作,你可以想像当表中有100万条记录时,你执行一条没有where语句的update指令时,在默认情况下数据库引擎会采用行锁,但这要记录100万条行锁记录,以及相关的意向共享锁,必定会消耗掉大量的系统资源,当系统资源不足时,数据库引擎会自动提升锁的级别,也就是由行锁提升为页锁,如果资源还是不足,则会再次提升,提升为表锁。
就以上例子来说,如果每个页可以放200条记录,则100万表记录的行锁转为5000个页锁,还省掉了大量的意向共享锁。如果资源还是一足,则可以再次提升锁级别,提升到表锁,这样就只需要一个锁就可以了。
愈大范围的锁花费在管理锁之上的资源就愈少。但相对来说,同时上线并发访问该资源的人数就越少。例如:或采用行锁,则你访问你的记录,我访问我的记录,互相不影响,但如果升级到页锁,则如果你先抢到该分页,而我要访问的记录又恰恰在这一分页上,则我必须要等你释放该分页之后才能访问。如果升级到表锁,则同一时间,该表中的记录只能一个人才能访问,其他人不能访问。如下图。

一般情况下,是不需要手工去设置锁定范围的,可以由Microsoft SQL Server 数据库引擎视情况而定,使用动态锁定策略确定最经济的锁。 执行查询时,数据库引擎会根据架构和查询的特点自动决定最合适的锁。 例如,为了缩减锁定的开销,优化器可能在执行索引扫描时在索引中选择页级锁。
动态锁定具有下列优点:
· 简化数据库管理。 数据库管理员不必调整锁升级阈值。
· 提高性能。 数据库引擎通过使用适合任务的锁使系统开销减至最小。
· 应用程序开发人员可以集中精力进行开发。 数据库引擎将自动调整锁定。
在 SQL Server 2008 中,锁升级的行为已发生改变,其中引入了 LOCK_ESCALATION选项
SQL SERVER的锁机制(四)——概述(各种事务隔离级别发生的影响)的更多相关文章
- (转)SQL SERVER的锁机制(四)——概述(各种事务隔离级别发生的影响)
六.各种事务隔离级别发生的影响 修改数据的用户会影响同时读取或修改相同数据的其他用户.即这些用户可以并发访问数据.如果数据存储系统没有并发控制,则用户可能会看到以下负面影响: · 未提交的依赖关系(脏 ...
- SQL SERVER的锁机制
SQL SERVER的锁机制(一)——概述(锁的种类与范围) SQL SERVER的锁机制(二)——概述(锁的兼容性与可以锁定的资源) SQL SERVER的锁机制(三)——概述(锁与事务隔离级别) ...
- 接上SQL SERVER的锁机制(一)——概述(锁的种类与范围)
二.完整的锁兼容性矩阵(见下图) 对上图的是代码说明:见下图. 三.下表列出了数据库引擎可以锁定的资源. 名称 资源 缩写 编码 呈现锁定时,描述该资源的方式 说明 数据行 RID RID 9 文件编 ...
- (转)SQL SERVER的锁机制(一)——概述(锁的种类与范围)
锁定:通俗的讲就是加锁.锁定是 Microsoft SQL Server 数据库引擎用来同步多个用户同时对同一个数据块的访问的一种机制. 定义:当有事务操作时,数据库引擎会要求不同类型的锁定,如相关数 ...
- SQL SERVER的锁机制(一)——概述(锁的种类与范围)
锁定:通俗的讲就是加锁.锁定是 Microsoft SQL Server 数据库引擎用来同步多个用户同时对同一个数据块的访问的一种机制. 定义:当有事务操作时,数据库引擎会要求不同类型的锁定,如相关数 ...
- (转)SQL SERVER的锁机制(三)——概述(锁与事务隔离级别)
五.锁与事务隔离级别 事务隔离级别简单的说,就是当激活事务时,控制事务内因SQL语句产生的锁定需要保留多入,影响范围多大,以防止多人访问时,在事务内发生数据查询的错误.设置事务隔离级别将影响整条连接. ...
- SQL SERVER的锁机制(三)——概述(锁与事务隔离级别)
五.锁与事务隔离级别 事务隔离级别简单的说,就是当激活事务时,控制事务内因SQL语句产生的锁定需要保留多入,影响范围多大,以防止多人访问时,在事务内发生数据查询的错误.设置事务隔离级别将影响整条连接. ...
- 【SQL SERVER】锁机制
锁定是 SQL Server 数据库引擎用来同步多个用户同时对同一个数据块的访问的一种机制. 基本概念 利用SQL Server Profiler观察锁 死锁产生的原因及避免 总结 基本概念 数据库引 ...
- Java中线程的锁和数据库中的事务隔离级别
当涉及到两个或多个线程操作同一个资源时,就会出现锁的问题. 数据库中的某一条记录或者是某一个对象中的字段,可以修改,也可以读取,一般情况下,读取的那个方法应该加锁(即用synchronized互斥), ...
随机推荐
- 微信小程序swiper制作内容高度不定的tab选项卡
微信小程序利用swiper制作内容高度不定的tab选项卡,不使用absolute定位,不定高度,由内容自由撑开主要思路是获取内容区的高度来给swiper动态设置值 .wxml <view cla ...
- SQL表两列取一列唯一值的记录
问下SQL表两列取一列唯一值的 A列 B列 C列 1001 AA 2012-01-02 1001 BB 2012-02-05 100 ...
- 设置默认Browser
电信A库要求android系统中有多个Browser时,开机自动设置一个默认浏览器,而不用弹出选择框让用户手动选择. 监听开机广播Intent.ACTION_BOOT_COMPLETED, 用Pack ...
- java多线程知识点
下面是我学习多线程记录的知识点,并没详细讲解每个知识点,只是将重要的知识点记录下来,有时间可以看看,如果有不对的地方,欢迎大家指出,谢谢! 1.多线程的状态和创建方式: 线程的状态: ...
- Eclipse编辑XML自动提示(zz)
Eclipse编辑XML自动提示 博客分类: j2se XMLEclipseiBATISSpringSQL IED Eclipse Java EE IDE for Web Developers: D ...
- Silverlight保存大数据到WCF出现Not Found问题
Silveright调用WCF保存大数据时,直接在客户端报“ 远程服务器返回了错误:Not Found ”问题,少量是没问题,如下图: 后面在这个文章中找到解决办法: http://www.cnblo ...
- 【轻松前端之旅】元素,标记,属性,<html>标签
HTML文档是由HTML元素定义的. HTML元素(element)指的是从开始标签(start tag)到结束标签(end tag)的所有代码. 有些元素会使用简写记法,如<img src=' ...
- Visual Studio 2015部署OpenCV
Visual Studio 2015的安装破解及OpenCV的安装和部署 平台:win10 X64+VS2015专业版 X64:vs2015.pro_chs+OpenCV 3.X:opencv-3.4 ...
- 2019.01.20 NOIP模拟 迅雷(kruskal/二分+并查集)
传送门 题意简述:给一张带权无向图,有a,ba,ba,b两类特殊点和普通点,问使得至少有一个aaa和一个bbb连通所需要的所有边边权最小值的最大值是多少. 思路: 一眼发现可以二分,考虑怎么check ...
- 2019.01.03 bzoj3456: 城市规划(生成函数+多项式取对)
传送门 生成函数好题. 题意:求n个点的简单(无重边无自环)无向连通图数目 思路: 对简单无向图构造生成函数f(x)=∑n2Cn2xnn!f(x)=\sum_n2^{C_n^2}\frac{x^n}{ ...