Sql Server2005之后,引入了一个新的隔离级别Snapshot(Read Committed Snapshot Isolation (RCSI))和(Snapshot Isolation (SI))
在之前的Sql Server隔离级别(1)中提到的四种隔离级别,除了Read Uncommitted之外,其他的三个隔离级别都会阻塞其他事务的执行(写锁会阻塞读锁,读锁也会阻塞写锁)。
这样带来的问题是启用这三个隔离级别将会造成性能的损失和并发量的下降,为了提供更好的并发量并且保持一定的数据一致性,Snapshot应运而生。
如果启用了Snapshot隔离,数据库会为提交的数据建立一个版本信息放在tempdb里。当一个事务开始的时候,会先从tempdb中读取最近一次提交的数据版本,这样就避免了读取的操作被写锁阻塞。
所以使用这个隔离级别,会带来更大的硬盘开销。当一个事务运行在Snapshot这个隔离级别下,为了维护版本信息,其他事务对数据的大量更新会导致tempdb中存储的版本信息非常多,不过SQL Server会将当前操作不再需要的版本信息从tempdb中删除。
而开头提到的Read Committed Snapshot Isolation (RCSI)和Snapshot Isolation (SI)都是使用相同的机制来实现数据的版本控制。不过通常会推荐使用Read Committed Snapshot Isolation (RCSI),相比Snapshot Isolation (SI)有如下好处。
1:Read Committed Snapshot Isolation (RCSI)只需要在数据库中开启相应配置即可,不需要改动现有的数据库代码,就可以从默认的Read Committed变成Read Committed Snapshot Isolation,读取操作将不会再被写操作阻塞。而Snapshot Isolation (SI)则需要在一个事务开始之前显示的声明。
2:Read Committed Snapshot Isolation (RCSI)的开销比Snapshot Isolation (SI)小,因为当一条语句结束之后,SQL Server将不会再为该语句维护行版本信息。而Snapshot Isolation (SI)是对一个事务的声明,对于运行比较久的事务,SQL Server需要在这个期间一直维护版本信息,对应产生的版本数据也就会非常多。
使用这两个隔离级别的方法如下:
Snapshot Isolation (RCSI):
在数据库中打开对应的配置即可
ALTER DATABASE DBNAME
SET READ_COMMITTED_SNAPSHOT ON
Snapshot Isolation (SI):
在数据库中打卡对应的配置,并且需要将一个事务的隔离级别显示声明为Snapshot
ALTER DATABASE DBNAME SET ALLOW_SNAPSHOT_ISOLATION ON
SET TRANSACTION ISOLATION LEVEL SNAPSHOT BEGIN TRAN --Statement END TRAN
本文基本上是对以下文章的理解和翻译,有兴趣的同学可以继续看看原文