T-SQL 重复读(Double Read)问题的理解
我的理解是:
step1,假设表里有100行有序记录, 事务1从row 1 开始读取到了row 50 并准备继续读取完这100行。
要注意的是,sql server 会自动释放已经读取了的row的锁。
step2,这时候,另外一个事务2 修改了 事务1已经读取并且被 sql server 释放掉锁的前面50行中的某些数据。
这修改操作导致了数据排序发生变化,可能原来已经读取了的第20行现在排到了50行后面去。
step3,然后,事务1继续读取剩下的数据。 就可能发现有数据被重复读取出来了。
demo如下:
1. 建立表和填充数据。
CREATE TABLE dbo.testDoubleRead
(
id int identity(10,1) PRIMARY KEY,
text_asc nvarchar(20)
)
go CREATE NONCLUSTERED INDEX IX_testDoubleRead_text_asc ON dbo.testDoubleRead(text_asc ASC); INSERT INTO dbo.testDoubleRead (text_asc)
VALUES('A'),('B'),('C'),('D')
注意非聚集索引的排序是 ASC,这时候表里的数据是:
SELECT * FROM dbo.testDoubleRead /* id text_asc
10 A
11 B
12 C
13 D */
2. 开一个新session,执行下面这段不完整的事务:
--SESSION 1 SCRIPT
BEGIN TRANSACTION UPDATE dbo.testDoubleRead
SET text_asc = 'UPDATE_C'
WHERE id = 12
3. 开另外一个session, 执行下面的查询:
SELECT * FROM dbo.testDoubleRead
显然,这查询是会被session1 block住的。
4. 回到session1, 执行完毕如下代码:
UPDATE dbo.testDoubleRead
SET text_asc = 'UPDATE_B_2'
WHERE id = 11 COMMIT TRANSACTION
5. 这时候, session2 会查询完毕,结果如下:
SELECT * FROM dbo.testDoubleRead /*
id text_asc
10 A
11 B
13 D
11 UPDATE_B_2
12 UPDATE_C
*/
可以看到,有两条 id = 11的记录!
再次分析下:
1。按照 非聚集索引的定义,刚开始的数据应该是这样的
/*
id text_asc
10 A
11 B
12 C
13 D
*/
2. session1 开启事务并修改了id=12 的行,但没有提交。 这时候,session2 尝试读取数据 但只能读取到 id=11的,不能再朝下读取了;除非session1 释放id=12 的行。
3. 接上面,session1 把id=12 的行修改了,根据非聚集索引的排序规则 text_asc ASC,可以确定值‘UPDATE_C’是应该排到最后一行的。 而且id=11的新值‘UPDATE_B’是在倒数第二行。
理想数据的样子应该是这样的:
/*
id text_asc
10 A
13 D
11 UPDATE_B_2
12 UPDATE_C
*/
4.session修改完id=11以后就提交,这样session2就可以继续之前的查询了。注意的是,session2在被block之前已经读取了: (id=11,text_asc='B')
5.综合上面的几点,session2继续按照非聚集索引的顺序读取(id=13开始),而不会清空之前已经读取完毕的(id=11,text_asc='B')。
所以最终的结果就是这样的了:
/*
id text_asc
10 A
11 B --在被session1的修改事务block之前读取了这行
13 D --session1提交事务以后,session2从这行继续读
11 UPDATE_B_2
12 UPDATE_C
*/
T-SQL 重复读(Double Read)问题的理解的更多相关文章
- mysql系列:加深对脏读、脏写、可重复读、幻读的理解
关于相关术语的专业解释,请自行百度了解,本文皆本人自己结合参考书和自己的理解所做的阐述,如有不严谨之处,还请多多指教. 事务有四种基本特性,叫ACID,它们分别是: Atomicity-原子性,Con ...
- [MySQL]对于事务并发处理带来的问题,脏读、不可重复读、幻读的理解
一.缘由 众所周知MySQL从5.5.8开始,Innodb就是默认的存储引擎,Innodb最大的特点是:支持事务.支持行级锁. 既然支持事务,那么就会有处理并发事务带来的问题:更新丢失.脏读.不可重复 ...
- SQL Server 中的事务与事务隔离级别以及如何理解脏读, 未提交读,不可重复读和幻读产生的过程和原因
原本打算写有关 SSIS Package 中的事务控制过程的,但是发现很多基本的概念还是需要有 SQL Server 事务和事务的隔离级别做基础铺垫.所以花了点时间,把 SQL Server 数据库中 ...
- MySQL Transaction--MySQL与SQL Server在可重复读事务隔离级别上的差异
MySQL和SQL Server两种数据库在REPEATABLE-READ事务隔离级别实现方式不同,导致使用上也存在差异. 在MySQL中,默认使用REPEATABLE-READ事务隔离级别,MySQ ...
- SQL Server中的事务与其隔离级别之脏读, 未提交读,不可重复读和幻读
原本打算写有关 SSIS Package 中的事务控制过程的,但是发现很多基本的概念还是需要有 SQL Server 事务和事务的隔离级别做基础铺垫.所以花了点时间,把 SQL Server 数据库中 ...
- 如何理解SQL的可重复读和幻读之间的区别?
从本源来理解比较容易理解,如果只是描述概念和定义,容易让人云里雾里找不到方向.正好这两天在浏览mysql的文档,我可以简单在这里总结一下,帮助其他还没有理解的朋友,如果有错误也麻烦帮忙指正. 先讲一点 ...
- Sql server脏读、更新丢失、不可重复读、幻象读问题及解决方案
1.脏读:一个事务读到另外一个事务还没有提交的数据.解决方法:把事务隔离级别调整到READ COMMITTED,即SET TRAN ISOLATION LEVEL READ COMMITTED.这时我 ...
- MySQL进阶15--TCL事务控制语言--建立结束事务/设置断点--默认隔离级别--脏读/幻读/不可重复读
#TCL事物控制语言 : /* Transaction control language : 事物控制语言 事务: 一个或者一组sql语句组成一个执行单元,这个执行单元要么全部执行,要么全部不执行; ...
- MySQL(25):事务的隔离级别出现问题之 不可重复读
1. 不可重复读 所谓的不可重复读(Non-Repeatable Read)是指事务中两次查询的结果不一致,原因是在查询的过程中其他事务做了更新的操作. 例如,银行在做统计报表的时候,第一次查询a账户 ...
- MySQL选用可重复读之前一定要想到的事情
原文地址:http://blog.itpub.net/29254281/viewspace-1398273/ MySQL选用可重复读隔离级别之前一定要想到的事情.间隙锁 MySQL在使用之前有三个务必 ...
随机推荐
- flask第十九篇——模板【3】
请关注微信公众号:自动化测试实战 今天我们继续模板的知识,现在我们增加字典的复杂度,这个时候在render_template第二个参数可以传**title,以后我们会用**context代替原来的ti ...
- ubutun Sogou输入法安装
http://jingyan.baidu.com/article/ad310e80ae6d971849f49ed3.html 文章来自以上链接 安装搜狗输入法 下载搜狗http://pinyin.so ...
- 【angularJS】Directive指令
AngularJS 通过被称为 指令 的新属性来扩展 HTML.指令是扩展的 HTML 属性,带有前缀 ng-. 内置指令 1.ng-app 指令初始化一个 AngularJS 应用程序. 定义了 A ...
- 获得消息的x,y的窗口内坐标(包括边框和titlebar高度
rectWindow = D2D.GetWindowRect(self.hwnd)#窗口大小 rectClient = D2D.GetWindowRect(self.hwnd,True)#客户区大小 ...
- 超详细的celery异步任务和定时任务的教程
转载自:https://segmentfault.com/a/1190000007780963
- python模块--如何相互调用自己写的模块
一.模块相互调用同级目录调用时的两种方法 import module print(module.add(3,8)) from module import add print(add(2,4)) 同级目 ...
- ubuntu 12.04lts 安装mysql ,并通过QT连接
安装server$ sudo apt-get install mysql-server 安装驱动 $ sudo apt-get install libqt4-sql-mysql $ dpkg --li ...
- Falcon
1. JE falcon还需要安装je用来处理jdbc,否则打不开falcon的页面,爆内部错误503,然后看异常信息:Caused by: org.apache.falcon.FalconExcep ...
- STM32的启动过程分析
对于stm32的启动过程一直心存疑惑.今天找了很多资料,进行了一个大致的分析. 1.cortex M3的复位过程(来自官方资料) 上述开机启动流程比较详细,内容较为全面,但部分步骤可以省略(红字可省略 ...
- 如何安装nginx第三方模块
nginx文件非常小但是性能非常的高效,这方面完胜apache,nginx文件小的一个原因之一是nginx自带的功能相对较少,好在nginx允许第三方模块,第三方模块使得nginx越发的强大. 在安装 ...