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在使用之前有三个务必 ...
随机推荐
- python字符串常用
参考这一篇: http://www.runoob.com/python/python-strings.html
- Cache应用中的服务过载案例研究
https://tech.meituan.com/avalanche-study.html
- MEF学习总结(2)---Primitive层
Primitive层是属于依赖注入的通用模型,主要有如下核心类型: 1. ComposablePart是核心类,他表示组件容器中的每一个组件,是对真正组件实例的包装.ExportDefinition属 ...
- 记一次socket_create()函数耗时异常记录
背景: 下午开发时突然整个页面耗时增加,空接口每次都需要2-3秒的耗时,一开始以为连开发环境数据库出现问题,最后断开数据库跑,发现还是很慢 最终逐步调试此页面耗时,定位到了socket_create( ...
- mysql binlog_format row and Statement 比较
两种模式的对比: Statement 优点 历史悠久,技术成熟: 产生的 binlog 文件较小: binlog 中包含了所有数据库修改信息,可以据此来审核数据库的安全等情况: binlog 可以用于 ...
- WebApi和Andriod对接上传和下载文件
我在实现webapi和Andriod客户端上传下载文件的时候默认的是以流的形式返回的,下面我就贴出最近在研究的对接文件的上传和下载代码以供各位大侠们参考: 上传文件接口: [HttpPost] pub ...
- Unit03: Spring Web MVC简介 、 基于XML配置的MVC应用 、 基于注解配置的MVC应用
Unit03: Spring Web MVC简介 . 基于XML配置的MVC应用 . 基于注解配置的MVC应用 springmvc (1)springmvc是什么? 是一个mvc框架,用来简化基于mv ...
- 使用Apache POI操作Excel文件---在已有的Excel文件中插入一行新的数据
package org.test; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundEx ...
- 杂项:SpagoBI
ylbtech-杂项:SpagoBI SpagoBI是一个商业智能平台,为商业智能项目提供了一个完整开源的解决方案.它涵盖了一个BI系统所有方面的功能包括:数据挖掘.查询.分析.报告.Dashboar ...
- nginx web服务器应用
Nginx介绍 Nginx是一个开源的,支持高性能,高并发的www服务和代理服务软件,因具有高并发(特别是静态资源),占用系统资源少等特性,且功能丰富而逐渐流行起来.功能应用上,Nginx不但是一个优 ...