SQL Server 2005 引入了新的快照隔离级别,可以提高 OLTP 应用程序的并发性。在以前版本的 SQL Server 中,并发性只是基于锁定,这就造成某些应用程序出现阻断和死锁的问题。相反,快照隔离依赖于行版本控制的增强功能,旨在通过避免读取器和编写器的阻止情况,来提高性能。
启用快照隔离之后,每个事务的已更新行版本在 tempdb 中维护。唯一的事务序列号标识每个事务,并且为每个行版本记录这些唯一的编号。事务使用序列号在事务序列号之前的最新行版本。事务将忽略在事务开始之后创建的更新的行版本。
“快照”一词反映的情况是:事务中的所有查询根据事务开始那一刻数据库的状态,看到数据库的相同版本(即快照)。不会在快照事务中的基础数据行或数据页上获取锁,这样可以执行其他事务,而不会被以前未完成的事务所阻止。修改数据的事务不会阻止读取数据的事务,读取数据的事务不会阻止写入数据的事务,就好像通常情况下在 SQL Server 中使用默认的 READ COMMITTED 隔离级别一样。这种无阻止的行为也大大降低了复杂事务出现死锁的可能性。
快照隔离使用开放式并发模型。如果快照事务尝试提交对事务开始后更改过的数据的修改,事务将回滚并将引发错误。对访问要修改的数据的 SELECT 语句使用 UPDLOCK 提示,可以避免此问题。有关更多信息,请参见“SQL Server 联机图书”中的“锁定提示”。
在事务中使用快照隔离之前,必须先通过设置 ALLOW_SNAPSHOT_ISOLATION ON 数据库选项来启用快照隔离。这样将激活在临时数据库 (tempdb) 中存储行版本的机制。在每个要将快照隔离与 Transact-SQL ALTER DATABASE 语句一起使用的数据库中,必须启用快照隔离。从这个方面来说,快照隔离与传统的隔离级别 READ COMMITTED、REPEATABLE READ、SERIALIZABLE 和 READ UNCOMMITTED 不同,这些传统的隔离级别不需要任何配置。下列语句激活快照隔离,并将默认的 READ COMMITTED 行为替换为 SNAPSHOT:
ALTER DATABASE MyDatabase
SET ALLOW_SNAPSHOT_ISOLATION ON
ALTER DATABASE MyDatabase
SET READ_COMMITTED_SNAPSHOT ON
设置 READ_COMMITTED_SNAPSHOT ON 选项后,可以使用默认的 READ COMMITTED 隔离级别访问版本化的行。如果 READ_COMMITTED_SNAPSHOT 选项设置为 OFF,必须为每个会话显式设置 Snapshot 隔离级别,以便访问版本化的行。
执行 Transact-SQL 语句所使用的隔离级别确定其锁定行为和行版本化行为。隔离级别的作用域为整个连接,使用 SET TRANSACTION ISOLATION LEVEL 语句为连接设置了隔离级别后,在连接关闭或设置了另一个隔离级别之前,该隔离级别将一直生效。但是,在连接内发出的各个查询可能包含锁提示,用于修改单个语句或事务的隔离,但是不影响连接的隔离级别。在存储过程或函数中设置的隔离级别或锁提示不会更改调用这些存储过程或函数的连接的隔离级别,并且只在存储过程或函数调用期间生效。
SQL-92 标准中定义了四个隔离级别,这四个隔离级别在以前版本的 SQL Server 中即受到支持:
-
READ UNCOMMITTED 是限制性最弱的隔离级别,因为该级别忽略其他事务放置的锁。使用 READ UNCOMMITTED 级别执行的事务,可以读取尚未由其他事务提交的修改后的数据值;这些行为称为“脏”读。
-
READ COMMITTED 是 SQL Server 默认的隔离级别。该级别通过指定语句不能读取其他事务已修改但是尚未提交的数据值,禁止执行脏读。在当前事务中的各个语句执行之间,其他事务仍可以修改、插入或删除数据,从而产生无法重复的读操作,或“影子”数据。
-
REPEATABLE READ 是比 READ COMMITTED 限制性更强的隔离级别。该级别包括 READ COMMITTED,并且另外指定了在当前事务提交之前,其他任何事务均不可以修改或删除当前事务已读取的数据。并发性低于 READ COMMITTED,因为已读数据的共享锁在整个事务期间持有,而不是在每个语句结束时释放。
-
SERIALIZABLE 是限制性最强的隔离级别,因为该级别锁定整个范围的键,并一直持有锁,直到事务完成。该级别包括 REPEATABLE READ,并增加了在事务完成之前,其他事务不能向事务已读取的范围插入新行的限制。
以上内容转自MSDN……