SQL Server 语句的锁定行为和行版本控制行为。
TRANSACT-SQL 语法约定
语法
-- Syntax for SQL Server and Azure SQL Database
SET TRANSACTION ISOLATION LEVEL
{ READ UNCOMMITTED
| READ COMMITTED
| REPEATABLE READ
| SNAPSHOT
| SERIALIZABLE
}
-- Syntax for Azure SQL Data Warehouse and Parallel Data Warehouse
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
参数
指定语句可以读取已由其他事务修改但尚未提交的行。
这是隔离级别中限制最少的级别。
SQL Server 中,您还可以使用下列任意一种方法,在保护事务不脏读未提交的数据修改的同时尽量减少锁定争用:
-
READ COMMITTED 隔离级别,并将 READ_COMMITTED_SNAPSHOT 数据库选项设置为 ON。
-
SNAPSHOT 隔离级别。
SQL Server 的默认设置。
READ COMMITTED 的行为取决于 READ_COMMITTED_SNAPSHOT 数据库选项的设置:
-
页锁在读取下一页时释放,表锁在语句完成时释放。
备注
不使用锁来防止其他事务更新数据。
在快照隔离模式下,事务中任何语句读取的 FILESTREAM 数据都将是在事务开始时便存在的数据的事务性一致版本。
当 READ_COMMITTED_SNAPSHOT 数据库选项设置为 ON 时,您可以使用 READCOMMITTEDLOCK 表提示为 READ COMMITTED 隔离级别上运行的事务中的各语句请求共享锁,而不是行版本控制。
备注
数据库不必处于单用户模式。
指定语句不能读取已由其他事务修改但尚未提交的行,并且指定,其他任何事务都不能在当前事务完成之前修改由当前事务读取的数据。
此选项只在必要时使用。
其效果就好像事务中的语句获得了已提交数据的快照,因为该数据在事务开始时就存在。
写入数据的事务也不会阻止 SNAPSHOT 事务读取数据。
当事务取得授权之后,便会立即释放锁。
如果使用 SNAPSHOT 隔离级别的事务访问多个数据库中的数据,则必须在每个数据库中将 ALLOW_SNAPSHOT_ISOLATION 都设置为 ON。
事务在第一次访问数据时启动。
例如,如果事务对表执行 UPDATE,然后对同一个表发出 SELECT 语句,则修改后的数据将包含在结果集中。
备注
在快照隔离模式下,事务中任何语句读取的 FILESTREAM 数据都将是在事务开始(而非语句开始)时便存在的数据的事务性一致版本。
请指定下列内容:
-
语句不能读取已由其他事务修改但尚未提交的数据。
-
任何其他事务都不能在当前事务完成之前修改由当前事务读取的数据。
-
在当前事务完成之前,其他事务不能使用当前事务中任何语句读取的键值插入新行。
该选项的作用与在事务内所有 SELECT 语句中的所有表上设置 HOLDLOCK 相同。
Remarks
事务中执行的所有读取操作都会在指定的隔离级别的规则下运行,除非语句的 FROM 子句中的表提示为表指定了其他锁定行为或版本控制行为。
例如,如果 REPEATABLE READ 事务具有用于某行的共享锁,并且该事务随后修改了该行,则共享行锁便会转换为排他行锁。
但是,可以将在 SNAPSHOT 隔离中启动的事务更改为任何其他隔离级别。
例如,如果某个事务从 READ COMMITTED 更改为 SERIALIZABLE,则在该事务结束前,更改后所获取的共享锁将一直处于保留状态。
例如,如果在批处理中设置 REPEATABLE READ,并且该批处理调用一个将隔离级别设置为 SERIALIZABLE 的存储过程,则当该存储过程将控制返回给该批处理时,隔离级别就会恢复为 REPEATABLE READ。
备注
表提示 (Transact-SQL)。
使用 SET TRANSACTION ISOLATION LEVEL 更改某个会话的隔离级别设置时,不会影响与该会话绑定的其他任何会话的设置。
SET TRANSACTION ISOLATION LEVEL 会在执行或运行时生效,而不是在分析时生效。
针对堆的优化大容量负载操作阻塞了运行在以下隔离级别下面的查询:
-
SNAPSHOT
-
READ UNCOMMITTED
-
使用行版本控制的 READ COMMITTED
批量导入和导出数据 (SQL Server)。
已启用 FILESTREAM 的数据库支持下列事务隔离级别。
| 隔离级别 | Transact SQL 访问 | 文件系统访问 |
|---|---|---|
| 未提交读 | SQL Server 2017 | 不支持 |
| 已提交读 | SQL Server 2017 | SQL Server 2017 |
| 可重复读 | SQL Server 2017 | 不支持 |
| 可序列化 | SQL Server 2017 | 不支持 |
| 读提交的快照 | SQL Server 2017 | SQL Server 2017 |
| 快照 | SQL Server 2017 | SQL Server 2017 |
示例
SQL Server 将所有共享锁一直保持到事务结束为止。
USE AdventureWorks2012;
GO
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
GO
BEGIN TRANSACTION;
GO
SELECT *
FROM HumanResources.EmployeePayHistory;
GO
SELECT *
FROM HumanResources.Department;
GO
COMMIT TRANSACTION;
GO