隔离级别
与应用程序进程相关联的隔离级别确定该进程所访问的数据被锁定或者与其他同时执行的进程相隔离的程度。 该隔离级别在工作单元运行期间生效。
- 应用程序读取或更新的行可供其他同时执行的应用程序进程使用的程度
- 其他同时执行的应用程序进程的更新活动可以影响应用程序的程度
静态 SQL 语句的隔离级别是作为程序包的属性指定的,并且将应用于使用该程序包的应用程序进程。 要指定隔离级别,请在程序准备过程中设置
ISOLATION 绑定或预编译选项。 对于动态 SQL 语句而言,缺省隔离级别是对准备该语句的程序包指定的隔离级别。 请使用
SET CURRENT ISOLATION 语句对会话中发出的动态 SQL 语句指定另一隔离级别。 有关更多信息,请参阅 CURRENT ISOLATION 专用寄存器
。 对于静态 SQL 语句和动态 SQL 语句而言,select-statement
中的 isolation-clause
都将覆盖专用寄存器(如果已设置的话)和绑定选项值。 有关更多信息,请参阅 Select-statement
。
隔离级别由锁定实施,所使用的锁定的类型将限制或阻止并发应用程序进程访问数据。 已声明临时表以及它们的行无法被锁定,这是因为它们仅可供声明它们的应用程序访问。
- 共享 (S)
- 挂起 S 锁定之后,并发应用程序进程只能对数据执行只读操作。
- 更新 (U)
- 挂起 U 锁定之后,如果并发应用程序进程未声明它们要更新行,那么它们只能对数据执行只读操作。 数据库管理器假定当前正在查看行的进程可能会更新该行。
- 互斥 (X)
- 挂起 X 锁定之后,并发应用程序进程将无法以任何方式访问数据。 这不适用于隔离级别为“未落实的读”(UR) 的应用程序进程,这些进程能够读取但无法修改数据。
下面是每种隔离级别的详细描述,这些描述按隔离级别对性能的影响程度的降序排列,但按您访问或更新数据时需要加以关注的程度的升序排列。
可重复的读 (RR)
可重复的读隔离级别将锁定应用程序在工作单元 (UOW) 运行期间引用的所有行。 如果应用程序在同一个工作单元中发出 SELECT 语句两次,那么每次将返回相同的结果。 对于 RR 而言,不可能出现丢失更新、访问未落实的数据、不可重复的读以及幻像读等情况。
在 RR 隔离级别下,应用程序在 UOW 完成前可以任意次地检索和处理行。 但是,在该 UOW 完成之前,其他应用程序均无法更新、删除或插入将会影响结果集的行。 在 RR 隔离级别下运行的应用程序无法看到其他应用程序所作的未落实更改。 此隔离级别确保返回的所有数据在被应用程序看到前保持不变,即使使用了临时表或行分块方法也是如此。
所引用的每一行都将被锁定,而不仅仅是锁定所检索的行。 例如,如果扫描 10000 行并对它们应用谓词,尽管可能只有 10 行满足条件,但仍会锁定全部的 10000 行。 其他应用程序无法插入或更新再次执行查询时将被添加到该查询所引用的行列表中的行。 这将防止出现幻像读情况。
由于 RR 可能会获取相当多的锁定,所以此数目可能会超出 locklist 和 maxlocks 数据库配置参数所指定的限制。 为了避免锁定升级,在有可能发生锁定升级的时候,优化器可能会选择获取单个表级别锁定用于索引扫描。 如果您不希望进行表级别锁定,那么请使用“读稳定性”隔离级别。
评估引用约束时,DB2 服务器有时会将用于外表扫描的隔离级别升级到 RR,而不考虑用户先前设置的隔离级别。 这将导致其他锁定一直被挂起到落实为止,从而增加发生死锁或锁定超时情况的可能性。 为了避免这些问题,请创建只包含外键列的索引以供引用完整性扫描使用。
读稳定性 (RS)
读稳定性隔离级别只锁定应用程序在工作单元运行期间检索的那些行。 RS 确保在 UOW 完成之前,在该 UOW 运行期间读取的任何合格行不会被其他应用程序进程更改,并确保由另一个应用程序进程对行进行的更改在该进程落实更改前无法被读取。 对于 RS 而言,不可能出现访问未落实的数据以及不可重复的读等情况。 但是,有可能进行幻像读。 对行进行的并行更新还可能引入幻像读,在幻像读中,旧值不满足原始应用程序的搜索条件,但新更新值满足。
- 应用程序进程 P1 读取满足某个搜索条件的行集 n。
- 然后应用程序进程 P2 插入满足该搜索条件的一行或多行并落实这些新插入操作。
- P1 使用同一搜索条件再次读取该行集并同时获得原始行和 P2 插入的行。
在 Db2 pureScale® 环境中,如果在此隔离级别运行的应用程序在另一 成员上同时更新先前已落实的行值,那么该应用程序可能会拒绝该行值。 要覆盖此行为,请指定 WAIT_FOR_OUTCOME 选项。
此隔离级别确保返回的所有数据在被应用程序看到前保持不变,即使使用了临时表或行分块方法也是如此。
RS 隔离级别既提供了高度的并行性,也提供了稳定的数据视图。 所以,优化器确保在发生锁定升级前不获取表级别锁定。
- 在并发环境中运行
- 要求合格行在工作单元运行期间保持稳定
- 在工作单元中不会多次发出同一个查询,或者在一个工作单元中多次发出同一个查询时并不要求结果集相同
游标稳定性 (CS)
游标稳定性隔离级别将在游标定位于事务执行期间所访问的任何行上时锁定该行。 此锁定在下一行被访存或者事务终止之前将保持有效。 但是,如果更改了该行中的任何数据,那么在落实更改之前将一直挂起该锁定。
在此隔离级别下,其他应用程序无法在可更新游标定位于某一行上时更新或删除该行。 在 CS 下,无法访问其他应用程序未落实的数据。 但是,有可能进行不可重复的读和幻像读。
CS 是缺省隔离级别。 如果您希望最大程度地提高并行性,并且只需要查看已落实的数据时,此隔离级别适用。 在此隔离级别下执行的扫描按配置参数 cur_commit(当前已落实)的设置运行。
在 Db2 pureScale 环境中,如果在此隔离级别运行的应用程序在另一个 成员上同时更新了先前已落实的行值,那么该应用程序可能会返回或拒绝该行值。 并行访问权解析设置的 WAIT FOR OUTCOME 选项可用于覆盖此行为。
未落实的读 (UR)
未落实的读隔离级别允许应用程序访问其他事务未落实的更改。 并且,UR 不会阻止其他应用程序访问正被读取的行,除非该应用程序尝试更改或删除表。
在 UR 下,可能会出现访问未落实的数据、不可重复的读以及幻像读等情况。 如果对只读的表运行查询,或者只发出 SELECT 语句并且查看其他应用程序尚未落实的数据不会引起问题时,此隔离级别适用。
- 只读游标可访问其他事务未落实的大部分更改。
- 在事务处理期间,正由其他事务创建或删除的表、视图和索引不可用。 其他事务进行的任何其他更改在落实或回滚前都可被读取。 在 UR 下,可更新游标的工作方式就像隔离级别为 CS 一样。
- 将该应用程序中的游标修改为明确游标。 将 SELECT 语句更改为包括 FOR READ ONLY 子句。
- 保留应用程序中的模糊游标,但对该程序进行预编译或者对其进行绑定并指定 BLOCKING ALL 和 STATICREADONLY YES 选项,以便允许该程序运行时将模糊游标视为只读游标。
ISOLATION LEVEL UR 在按列组织的表与按行组织的表上的行为可能有所不同。
隔离级别的比较
UR | CS | RS | RR | |
---|---|---|---|---|
应用程序是否能够看到其他应用程序进程未落实的更改? | 是 | False | False | False |
应用程序是否能够更新其他应用程序进程未落实的更改? | False | False | False | False |
重新执行语句时是否会被其他应用程序进程影响? 1 | 是 | 是 | 是 | 否2 |
已更新的行是否能够被其他应用程序进程更新? 3 | False | False | False | False |
已更新的行是否能够被其他在除 UR 以外的隔离级别下运行的应用程序进程读取? | False | False | False | False |
已更新的行是否能够被其他在 UR 隔离级别下运行的应用程序进程读取? | 是 | 是 | 是 | 是 |
已访问的行是否能够被其他应用程序进程更新? 4 | 是 | 是 | False | False |
已访问的行是否能够被其他应用程序进程读取? | 是 | 是 | 是 | 是 |
当前行是否能够被其他应用程序进程更新或删除? 5 | 是/否6 | 是/否6 | False | False |
注:
|
隔离级别摘要
隔离级别 | 访问未落实的数据 | 不可重复的读 | 幻像读 |
---|---|---|---|
可重复的读 (RR) | 不可能 | 不可能 | 不可能 |
读稳定性 (RS) | 不可能 | 不可能 | 可能 |
游标稳定性 (CS) | 不可能 | 可能 | 可能 |
未落实的读 (UR) | 可能 | 可能 | 可能 |
应用程序类型 | 要求数据高度稳定 | 不要求数据高度稳定 |
---|---|---|
读写事务 | RS | CS |
只读事务 | RR 或 RS | UR |