事务指定一个隔离级别,该隔离级别定义一个事务与其他事务相隔离的程度。 隔离是指将不同事务所作的资源或数据修改彼此隔离。 隔离级别从允许的并发副作用(例如脏读或虚拟读取)的角度进行描述。
事务隔离级别控制以下效果:
读取数据时是否获取锁,以及请求的是何种类型的锁。
持有读锁的时长。
引用其他事务修改的行的读取操作是否:
阻塞,直到该行上的排他锁被释放。
获取在语句或事务开始时存在的该行的已提交版本。
读取未提交的数据更改。
选择隔离级别
选择事务隔离级别不影响为保护数据修改而获取的锁。 事务总是会对它修改的任何数据加排他锁。 它在事务完成之前持有该锁,不管为该事务设置了什么样的隔离级别。 对于读取操作,事务隔离级别主要定义如何保护操作免受其他事务的影响。
较低的隔离级别可以增强许多用户同时访问数据的能力, 但也增加了用户可能遇到的并发副作用(例如脏读或丢失更新)的数量。 相反,较高的隔离级别减少了用户可能遇到的并发副作用的类型, 但需要更多的系统资源,并增加了一个事务阻塞其他事务的可能性。 应平衡应用程序的数据完整性要求与每个隔离级别的开销,在此基础上选择相应的隔离级别。
最高隔离级别(可序列化)保证事务在每次重复读取操作时都能准确检索到相同的数据, 但它使用某种级别的锁定,而锁定可能会影响多用户系统中的其他用户。 最低的隔离级别“未提交读”可以读取已被其他事务修改但尚未提交的数据。 在未提交读取中,所有并发副作用都可能发生,但因为没有读取锁定或版本控制,所以开销最少。
备注
下表显示了不同隔离级别允许的并发副作用。
| 隔离级别 | 脏读 | 不可重复读 | 幻影 |
|---|---|---|---|
| 读未提交 | 是 | 是 | 是 |
| 读已提交 | 否 | 是 | 是 |
| 可重复读 | 否 | 否 | 是 |
| 快照 | 否 | 否 | 否 |
| 可序列化 | 否 | 否 | 否 |
事务必须至少在可重复读取的隔离级别运行,才能在两个事务都检索同一行时防止丢失更新。 该事务随后根据最初检索到的值更新该行。 如果两个事务使用单个 UPDATE 语句更新行,并且不基于以前检索的值进行更新,则丢失的更新不能在已提交的读取的默认隔离级别发生。
若要为事务设置隔离级别,可以使用 SQLServerConnection 类的 setTransactionIsolation 方法。 此方法接受 int 值作为其参数,此参数基于如下所示的连接常量之一:
con.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
若要使用 SQL Server 的新的快照隔离级别,可以使用 SQLServerConnection 常量之一:
con.setTransactionIsolation(SQLServerConnection.TRANSACTION_SNAPSHOT);
或者,您可以使用:
con.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED + 4094);
有关 SQL Server 隔离级别的详细信息,请参阅 SQL Server 联机丛书中的“数据库引擎 中的隔离级别”。
另请参阅
通过 JDBC 驱动程序执行事务
SET TRANSACTION ISOLATION LEVEL (Transact-SQL)