Notes on ‘Expert Oracle’ — No.7.2: Concurrency–Write Consistency

1. You have already known about "Read Consistency" — 如果数据在语句/事务开始时没变化,就返回这行数据;否则,从回滚段里读它的Snapshot. 这叫做"Consistent Read"

2. 与之相对的是
“Current Read” — 不去读回滚段,而是从当前数据文件里去读

   a. When does it happen? 在准备修改数据时进行Current Read

   b. 举例说明,

       Update t set y = 1 where x = 5
          i.首先会执行 "select .. from t where x = 5",这个过程使用的是"Consistent Read",即找到回滚段里满足 x = 5的记录
           ii.在准备执行 "set y = 1" 时会再检查一下数据文件中该条记录是否仍满足 "x = 5".这个过程使用的就是"Current Read"
        iii.如果这时该记录已经被另一个事务变成了"x = 6"了,那会怎么办?

3.
如果"current read"时发现数据已经变了(不再满足原来的where条件),则重启整条语句。

    a.重启后的执行步骤和原来一样,也是先用Consistent Read找到记录,再通过Current Read判断数据是否已经不再满足where条件

    b.唯一的不同是重新运行时会用 select … for update 找到数据并锁住

    c.如果重启后执行仍不成功,则再次重启,如此往复…

4.
重启的后果:

   a.
Before类型的触发器会执行两次!“试修改”时执行一次,正式修改时又执行一次!

   b.
重启可能会影响性能
如果一条语句在更新1000条记录被其它事务引发重启,该条语句又要从头开始运行,前面的1000条更新都白做了。

5.
Before类型的触发器本身也可能引发重启。如果这类触发器引用的列值与Where子句中的列值有交叠,那它在执行时也会做一下Current Read,然后与where子句中的条件进行比较,如果不一致就会引发重启。所以用这种触发器时要小心。

  

Leave a Comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.