控制到 SQL Server 的连接发出的 Transact-SQL 语句的锁定行为和行版本控制行为。
一次只能设置一个隔离级别选项,而且设置的选项将一直对那个连接始终有效,直到显式更改该选项为止。事务中执行的所有读取操作都会在指定的隔离级别的规则下运行,除非语句的 FROM 子句中的表提示为表指定了其他锁定行为或版本控制行为。
事务隔离级别定义了可为读取操作获取的锁类型。针对 READ COMMITTED 或 REPEATABLE READ 获取的共享锁通常为行锁,尽管当读取引用了页或表中大量的行时,行锁可以升级为页锁或表锁。如果某行在被读取之后由事务进行了修改,则该事务会获取一个用于保护该行的排他锁,并且该排他锁在事务完成之前将一直保持。例如,如果 REPEATABLE READ 事务具有用于某行的共享锁,并且该事务随后修改了该行,则共享行锁便会转换为排他行锁。
在事务进行期间,可以随时将事务从一个隔离级别切换到另一个隔离级别,但有一种情况例外。即在从任一隔离级别更改到 SNAPSHOT 隔离时,不能进行上述操作。否则会导致事务失败并回滚。但是,可以将在 SNAPSHOT 隔离中启动的事务更改为任何其他隔离级别。
将事务从一个隔离级别更改为另一个隔离级别之后,便会根据新级别的规则对更改后读取的资源执行保护。在更改前读取的资源将继续按照以前级别的规则受到保护。例如,如果某个事务从 READ COMMITTED 更改为 SERIALIZABLE,则在该事务结束前,更改后所获取的共享锁将一直处于保留状态。
如果在存储过程或触发器中发出 SET TRANSACTION ISOLATION LEVEL,则当对象返回控制时,隔离级别会重设为在调用对象时有效的级别。例如,如果在批处理中设置 REPEATABLE READ,并且该批处理调用一个将隔离级别设置为 SERIALIZABLE 的存储过程,则当该存储过程将控制返回给该批处理时,隔离级别就会恢复为 REPEATABLE READ。
注意 |
---|
用户定义的函数和公共语言运行时 (CLR) 用户定义的类型无法执行 SET TRANSACTION ISOLATION LEVEL。但是,可通过使用表提示来重写隔离级别。有关详细信息,请参阅表提示 (Transact-SQL)。 |
当您使用 sp_bindsession 绑定两个会话时,每个会话都会保留它自身的隔离级别设置。使用 SET TRANSACTION ISOLATION LEVEL 更改某个会话的隔离级别设置时,不会影响与该会话绑定的其他任何会话的设置。
SET TRANSACTION ISOLATION LEVEL 会在执行或运行时生效,而不是在分析时生效。
针对堆的优化大容量负载操作阻塞了运行在以下隔离级别下面的查询:
-
SNAPSHOT
-
READ UNCOMMITTED
-
使用行版本控制的 READ COMMITTED
相反,运行在这些隔离级别下面的查询阻塞了针对堆的优化大容量负载操作。有关大容量加载操作的详细信息,请参阅关于大容量导入和大容量导出操作和优化大容量导入性能。
已启用 FILESTREAM 的数据库支持下列事务隔离级别。
隔离级别 | Transact SQL 访问 | 文件系统访问 |
---|---|---|
未提交读 | SQL Server 2008 | 不支持 |
已提交读 | SQL Server 2008 | SQL Server 2008 |
可重复读 | SQL Server 2008 | 不支持 |
可序列化 | SQL Server 2008 | 不支持 |
已提交读的快照 | SQL Server 2008 R2 | SQL Server 2008 R2 |
快照 | SQL Server 2008 R2 | SQL Server 2008 R2 |
以下示例为会话设置了 TRANSACTION ISOLATION LEVEL。对于每个后续 Transact-SQL 语句,SQL Server 将所有共享锁一直保持到事务结束为止。
USE AdventureWorks2008R2; GO SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; GO BEGIN TRANSACTION; GO SELECT * FROM HumanResources.EmployeePayHistory; GO SELECT * FROM HumanResources.Department; GO COMMIT TRANSACTION; GO