SQL Server的READ COMMITTED SNAPSHOT与SNAPSHOT


23

我正在研究SQL Server READ COMMITTED SNAPSHOTSNAPSHOT隔离级别之间的差异,并且遇到了以下资源:

选择基于行版本控制的隔离级别

对于大多数应用程序,由于以下原因,建议使用行版本控制的读取提交隔离而不是快照隔离:

  • 与快照隔离相比,它占用的tempdb空间更少。

  • 快照隔离很容易受到更新冲突的影响,这些更新冲突不适用于使用行版本控制读取已提交的隔离。当在快照隔离下运行的事务读取数据,然后由另一个事务修改该数据时,快照事务对同一数据的更新将导致更新冲突,并且该事务终止并回滚。使用行版本控制的读取提交隔离不是问题。

我对这些主题有些陌生,但是我似乎无法理解上面链接中的两个要点。

  1. 对于这些模式,为什么tempdb空间会有所不同?一个存储比另一个存储更多的粒度版本吗?

  2. 为什么快照隔离更容易受到更新冲突的影响?

Answers:


18
  1. READ COMMITTED SNAPSHOT在每个语句之后使用一个新的快照。这意味着可以保留更少的行版本。(您在文档中引用的语句有些误导,因为它表明这始终是正确的-仅在长时间运行的SNAPSHOT事务中才是正确的。)快照行版本是在写入时创建的。读取不会影响放入tempdb中的内容。作家可能无法预见将来会进行什么阅读。读者仅影响可以清除的内容。
  2. 当一个SNAPSHOT事务在开始写入与尝试写入之间的时间内写入T1由另一个事务修改的行时,该语句将失败,并出现更新冲突错误。这是一个乐观的并发模型。与将等待释放行上的X锁并正常继续。T2T1T1READ COMMITTED SNAPSHOT T1T2

1
对于#2,可以肯定地说SNAPSHOT并非仅锁定更新-它仅依赖行版本控制吗?
约翰·罗素

1
@JohnRussell它确实锁定以支持回滚。所有写操作都必须X锁定,以确保在发生回滚的情况下可以还原该行。
usr

0

快照和已提交读快照之间的另一个区别如下。

  1. 快照

在第一届会议

设置TRAN隔离级别快照开始TRAN SELECT * FROM TB1 ..... .....

在第二届会议

更新TB1 SET NAME = NAME +'test'其中id = 1

在第一届会议

SELECT * FROM TB1-这将返回ID = 1的值名称,而不是name +'test'COMMIT TRAN

在读取的已提交快照中,会话1中的第一个选择将返回id = 1的名称,第二个选择将返回名称+'test'。

因此,在快照隔离中,SQL SERVER在事务开始时创建一个快照,并在整个事务期间从该快照读取。

在已提交读快照中,将在事务期间为每个SELECT语句创建快照。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.