我们在Oracle和MySQL数据库中已经对一致性读的概念比较熟悉了,但是在SQL Server中却鲜少提及,但SQL Server自2005版本以来其实也实现了一致性读,几乎所有关系型数据库产品的一致性读都是通过MVCC机制实现的,说白了就是修改之前先把数据存一份儿。
MVCC的意思就是Multi-Version Concurrency Control--多版本并发控制,这里的version就是指的数据的前镜像,多了一份数据自然就减少了争用,增加了并发。
SQL Server数据库在Read committed snapshot和snapshot隔离级别下通过MVCC机制实现了一致性读,其机制如下:
MVCC一致性读步骤:
  • A new transaction is initiated, and it is assigned a transaction sequence number.
  • 每个事务开始时被分配一个事务序列号Transaction Sequence Number(TSN)。
  • The Database Engine reads a row within the transaction and retrieves the row version from tempdb whose sequence number is closest to, and lower than, the transaction sequence number.
  • 读事务通过数据库引擎在tempdb中检索TSN小于当前读事务TSN的行(这些行都带有各自事务的TSN信息)。
  • The Database Engine checks to see if the transaction sequence number is not in the list of transaction sequence numbers of the uncommitted transactions active when the snapshot transaction started.
  • 数据库引擎检查:步骤2中找到的行的TSN是否在未提交事务列表中,此列表中的未提交事务都是读事务启动时就已经处于active状态的事务。
  • The transaction reads the version of the row from tempdb that was current as of the start of the transaction. It will not see new rows inserted after the transaction was started because those sequence number values will be higher than the value of the transaction sequence number.
  • 当前事务只读取:离当前读事务TSN最近,且小于当前读事务TSN的行版本。这意味只读取最新的已提交数据。
  • The current transaction will see rows that were deleted after the transaction began, because there will be a row version in tempdb with a lower sequence number value.
  • 当前事务永远不会读取到其他事物的未提交修改,因为在tempdb中总会存在修改行的行版本(即前镜像)。

需要考虑的一种情形是:

在读事务开始后有其他DML事务修改、插入、删除数据并在读到数据之前就提交,那么读事务会不会读取到这些更新?
由于条件所限,还未进行测试,但是猜测如下:
不会读取到更新,因为这些行版本会在tempdb中保留一段时间(同一数据可能存在多个行版本),只要检测到这些行版本的TSN大于当前读事务的TSN那么就意味着这些行在读事务开启后经过了修改,读事务只要找到这些行版本中TSN最新的一个就可以。
如果猜测正确那么也意味着tempdb中的行版本(即行的前镜像)是有保留时间的,类似于Oracle的Undo_retention。
如果猜测与实践不符,那么就意味着tempdb中的行版本会在事务提交后立马消失,读事务会读取到事务开始后的一部分提交的修改。
 
本文主要观点来自官网博客:
关于Read committed snapshot和snapshot隔离级别,参考http://www.cnblogs.com/leohahah/p/8464575.html

SQL Server 一致性读的更多相关文章

  1. 初谈SQL Server逻辑读、物理读、预读

    前言 本文涉及的内容均不是原创,是记录自己在学习IO.执行计划的过程中学习其他大牛的博客和心得并记录下来,之所以想写下来是为了记录自己在追溯的过程遇到的几个问题,并把这些问题弄清楚. 本章最后已贴出原 ...

  2. SQL Server逻辑读、预读和物理读

    SQL Server数据存储的形式 预读:用估计信息,去硬盘读取数据到缓存.预读100次,也就是估计将要从硬盘中读取了100页数据到缓存. 物理读:查询计划生成好以后,如果缓存缺少所需要的数据,让缓存 ...

  3. 初谈SQL Server逻辑读、物理读、预读【转】

    前言 本文涉及的内容均不是原创,是记录自己在学习IO.执行计划的过程中学习其他大牛的博客和心得并记录下来,之所以想写下来是为了记录自己在追溯的过程遇到的几个问题,并把这些问题弄清楚. 本章最后已贴出原 ...

  4. SQL Server一致性错误修复案例总结

    今天遇到了一个关于数据库一致性错误的案例.海外工厂的一台SQL Server 2005(9.00.5069.00 Standard Edition)数据库在做DBCC CHECKDB的时候出现了一致性 ...

  5. SQL Server 幻读 的真实案例

    数据库中有表[01_SubjectiveScoreInfo],要实现表中的数据只被查出一次,此表数据量较大,有三四百万数据.表结构也确实不是很合理,无法修改表结构,即使是新增一个字段也会有相当大的修改 ...

  6. Performance Monitor4:监控SQL Server的IO性能

    SQL Server的IO性能受到物理Disk的IO延迟和SQL Server内部执行的IO操作的影响.在监控Disk性能时,最主要的度量值(metric)是IO延迟,IO延迟是指从Applicati ...

  7. sql语句优化SQL Server

    MS   SQL   Server查询优化方法查询速度慢的原因很多,常见如下几种 1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷)          2.I/O吞吐量小,形成了 ...

  8. 整理:sql语句优化之SQL Server

    . 增加服务器CPU个数;但是必须明白并行处理串行处理更需要资源例如内存.使用并行还是串行程是MsSQL自动评估选择的.单个任务分解成多个任务,就可 以在处理器上运行.例如耽搁查询的排序.连接.扫描和 ...

  9. SQL Server优化查询

    1. 首先要搞明白什么叫执行计划? 执行计划是数据库根据SQL语句和相关表的统计信息作出的一个查询方案,这个方案是由查询优化器自动分析产生的,比如一条SQL语句如果用来从一个 10万条记录的表中查1条 ...

随机推荐

  1. 01 Windows安装Tensorflow

    1.安装Python. 点击此处下载Python3.5.2.安装Python时一定要选择安装pip. 2.配置Python环境变量. 将%安装路径%\Scripts添加到Path下面. 3.修改Pip ...

  2. 为什么LINQ to XML的性能要优于XmlDocument?

    一直很忙,压了很多贴,今天发一篇吧.后面的看心情吧. 今天群里有人问如何解析web.config方便,然后我就推荐了Linq to XML,然后就有人说“我宁可XmlDocument,再SeleteN ...

  3. Apache-httpd.conf详解

    ## Apache服务器主配置文件.  包括服务器指令的目录设置.# 详见 <URL:http://www.apache.org/docs/> ## 请在理解用途的基础上阅读各指令.## ...

  4. [转]angular官网 及 Ant Design of Angular

    https://angular.io/cli https://www.angular.cn/guide/quickstart https://ng.ant.design/docs/introduce/ ...

  5. C#设计模式之五原型模式(Prototype Pattern)【创建型】

    一.引言 在开始今天的文章之前先说明一点,欢迎大家来指正.很多人说原型设计模式会节省机器内存,他们说是拷贝出来的对象,这些对象其实都是原型的复制,不会使用内存.我认为这是不对的,因为拷贝出来的每一个对 ...

  6. Java 中变量初始化、子类和父类构造器调用的顺序

    先说结论 变量初始化 -> 父类构造器 -> 子类构造器 贴代码 Animcal.java 父类 public class Animal { private static int inde ...

  7. 5.枚举和注解_EJ

    第30条: 用enum代替int常量 枚举类型是指由一组固定的常量组成合法值得类型.例如一年中的季节,太阳系中的行星或一副牌中的花色.在开发中我们经常在类使用static final来定义一个int常 ...

  8. JavaScript中8个常见的陷阱

    译者按: 漫漫编程路,总有一些坑让你泪流满面. 原文: Who said javascript was easy ? 译者: Fundebug 为了保证可读性,本文采用意译而非直译.另外,本文版权归原 ...

  9. idea代码提示

    idea代码提示:Keymap-->Main menu-->Code-->Completion去掉Cyclic Expand Word的快捷键将Basic的快捷键更改为Alt+/

  10. js获取对象的长度

    var obj= { "name": "wuqian", "sex": "famale", "hello&qu ...