1. RR (Repeatable Read) 可重复读取
可重复读取的隔离级别是限制最严格的隔离级别。在使用它时,一个事务的影响与其他并发运行的事务的影响完全隔离。因此,丢失更新、脏读、不可重复读取和幻像都不会发生。
当使用可重复读取的隔离级别时,由拥有方事务以任何方式引用的每一行在该事务的寿命期间都被锁定。(With repeatable read, every row that's referenced in any manner by the owning transaction is locked for the duration of that transaction.)因此,如果在同一个事务中发出多次相同的查询(SELECT语句),那么产生的结果数据集可以保证是相同的。事实上,在可重复读取隔离级别下运行的事务可以检索同一行集任意次数,并且可以对它们执行任意次数的操作,直到(由提交或回滚操作)终止事务。但是,只要事务是活动的,就不允许其他事务执行会修改拥有方事务正在访问的一行或多行的插入、更新或删除操作。
为了确保在可重复读取隔离级别下运行的事务所访问的数据不会受到其他事务的负面影响,该隔离事务所引用的每一行都被锁定,而不是只锁定实际检索或修改的那些行。因此,如果一个事务扫描1000行数据是为了检索其中的10行,则在被扫描的所有1000行数据(而不仅仅是被检索的10行数据)上都会获得锁,并保持锁定。
请注意:在使用可重复读取隔离级别时,如果想要通过扫描整个表或视图来响应查询,那么无论是整个表还是视图所引用的所有行都会被锁定。这大大降低了并发性,在使用大表和视图时尤其如此。
2. RS (Read Stability) 读稳定性
读稳定性隔离级别的限制不如可重复读取隔离级别那么严格;因此,它没有将一个事务的影响与其他并发事务的影响完全隔离。在使用该隔离级别时,丢失更新、脏读和不可重复读取不会发生,但是可能会出现幻像。那是因为在使用读稳定性隔离级别时,只有隔离事务实际检索和修改的行会被锁定。(When this isolation level is used, only the rows that are actually retrieved or modified by the owning transaction are locked.)因此,如果一个事务为了检索10行数据而扫描1000行数据,那么只在被检索的10行(而不是所扫描的1000行)上提供锁,并保持锁定。由于需要较少的锁,所以可以并发运行更多事务。如果隔离事务执行多次相同的查询,那么每次产生的结果数据集可能都会有所不同。
与可重复读隔离级别一样,在读稳定性隔离级别下运行的事务可以检索一组行,并对它们执行任意次数的操作。只要该事务保持活动,就会禁止其他事务执行那些会影响该隔离事务所检索的那一组行的更新或删除操作。另一方面,允许其他事务对数据库中的任意表或可更新视图执行插入操作;如果所插入的行与隔离事务所发出的查询的选择条件相匹配,那么这些行可能作为幻像出现在后续产生的结果数据集中。
3. CS (Cursor Stability) 游标稳定性
游标稳定性隔离级别在隔离并发事务彼此间的影响方面甚至比读稳定性隔离级别还要宽松。在使用该隔离级别时,丢失更新和脏读不会发生,但有可能出现不可重复读取和幻像。这是因为在大多数情况下,在使用游标稳定性隔离级别时,只有被隔离事务引用的行被锁定。(in most cases, the cursor stability isolation level only locks the row that is currently referenced by a cursor that was declared and opened by the owning transaction.)在从结果数据集检索到记录的那一刻,指针(被称为游标)被定位于基础表中相应的行,并且该行被锁定。在游标被重新定位(往往不是由FETCH操作实现)时,或者在终止拥有方事务之后,该锁会一直有效。因为只获取一个行级别的锁,所以游标稳定性隔离级别提供了最高级别的并发性。因此,这是DB2默认使用的隔离级别。
当一个事务使用游标稳定性隔离级别(通过游标方式)从表中检索行时,只要游标定位在某一行上,那么其他事务均不允许更新或删除该行。但是,如果被锁定的行本身不是以索引方式访问的,那么其他事务就可以将新行添加到表中,并且可以对位于游标(锁定的行)任意一侧的行执行更新和删除操作。一旦获取了锁,该锁就一直有效,直到重新定位游标或终止拥有方事务。(在大部分情况下,如果重新定位游标,则会释放当前行上的锁,并在游标被移动到的另一行上获得新锁。)如果隔离事务修改了它检索到的任何行,那么在终止拥有方事务之前(也就是说,已经移动了游标,使之离开了被修改的行),其他事务均不允许更新或删除该行。
在使用游标稳定性隔离级别时,如果同一个查询在相同事务中执行两次或两次以上,那么所产生的多个结果可能会有所不同。此外,在提交由其他事务在其他行上所做的更改之前,这些更改将是不可见的。(这对于在可重复读取隔离级别和读稳定性隔离级别下运行的事务也是一样的。)
4. UR (Uncommited Read) 未提交的读取
未提交读取隔离级别是限制性最宽松的可用隔离级别。在使用该隔离级别时,一个事务的影响与其他并发事务的影响一般没有隔离。因此,脏读、不可重复读取和幻像可能会出现,并且的确经常出现。那是因为在使用未提交读取隔离级别时,仅当一个事务试图修改它所检索的行中存储的数据时,它所检索的这些行才会被锁定。(when this isolation level is used, rows retrieved by a transaction are only locked if another transaction attempts to drop or alter the table the rows were retrieved from.)或者,如果另一个事务试图删除或更改被检索的行所在的表时,这些行也会被锁定。因为在使用未提交读取隔离级别时,行通常保持未锁定状态,所以通常在事务访问仅读表和视图,以及在被执行的事务的检索或未提交数据没有负面效果的时候,才会使用未提交读取隔离级别。
顾名思义,在提交由其他事务对行所做的更改之前,在未提交读取隔离级别下运行的事务可以看见这些更改。但是,当其他事务创建表、索引或视图,情况则有所不同。在这些情况下,必须提交创建对象的事务,然后在未提交读取隔离级别下运行的事务才可以看见或访问这些对象。这同样适用于删除了现有的表、索引或视图的情况。直到提交了删除对象的事务之后,在未提交读取隔离级别下运行的事务才会知道这些对象已不存在。(要注意一个要点是,当在该隔离级别下运行的事务使用可更新游标时,该事务的行为就像它在游标稳定性隔离级别下运行一样,并且游标稳定性隔离级别的约束也适用。)




