可重复读隔离级别(ANSI 可串行化和 ANSI 可重复读)是最严格的隔离级别。使用“可重复读”,数据库服务器锁定事务持续期间检查到的(不仅仅是取得的)所有行。
图: 为可重复读加上的锁定
set isolation to repeatable read begin work declare cursor for SELECT * FROM customer open the cursor while there are more rows fetch a row do work end while close the cursor commit work
在检查多行的处理过程中,“可重复读”十分有用,但在事务期间不能做任何更改。 例如:假设某个应用程序必须检查属于一个人的三个帐户的帐户结余。 该应用程序首先得到第一个帐户的结余,然后得到第二个。 但是,在同一个时刻,另外一个应用程序开始了一个事务,该事务为第三个帐户登入借方并为第一个帐户贷款。 在原先的应用程序获得第三个帐户的帐户结余时,该帐户已被记入借方。 但是,原先的应用程序没有记录第一个帐户的借方。
在使用“已落实读取”或“游标稳定”时,就会发生上述情况。 而使用“可重复读”就不会发生这种情况。 由于初始应用程序在事务结束之前都会为每个接受检查的帐户保持一个读取锁定,所以第二个应用程序对第一个帐户的更改尝试将失败(或等待,这取决于 SET LOCK MODE)。
因为即使被检查的行被锁定,如果数据库服务器顺序读取该表的话,与查询结果无关的大量的行也会被锁定。 基于这个原因,当数据库服务器可以用索引访问一个表时就会使用“可重复读”隔离。 如果存在索引,而优化器选择了顺序扫描,那么您可以使用强制使用索引的指令。 但是,强制在查询路径中进行更改可能会对查询性能产生负面影响。