程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> Oracle數據庫 >> Oracle數據庫基礎 >> 淺述當前模式讀與一致性讀續

淺述當前模式讀與一致性讀續

編輯:Oracle數據庫基礎

在上一篇《淺述當前模式讀與一致性讀的區別》文章裡,我用2個特殊例子描述當前模式讀和一致性讀之間的區別,並提到了“如在事務啟動後到數據塊被讀取之間的這段時間內,相應的數據塊發生了改變,那麼可能就會有我們意想不到的事情發生”。而這樣的意想不到的結果可能能被我們接受,但也可能難以被接受。

我們先看一下以下2條UPDATE語句:

  1. 1:    
  2. update t_test1 set lio=0 where object_id in (101,102);    
  3. 2:    
  4. update t_test1 set lio=(select lio from t_test1 where object_id = 101) where object_id = 102 and (select count(*) from t_test2 t1, t_test2 t2) > 0;   

從邏輯角度來說,無論運行了那條語句,我們希望兩條記錄(object_id=101和object_id=102)的lio都相同。

然而,由於UPDATE語句會同時引入一致性讀和當前模式讀,並且由於這兩種讀之間存在時間差,我們可能會得到不希望出現的結果。

這裡我們演示一個例子。

  1. 13:27:23 HELLODBA.COM>update t_test1 set lio=1 where object_id in (101,102);    
  2.     
  3. rows updated.    
  4.     
  5. 13:29:06 HELLODBA.COM>commit;    
  6.     
  7. Commit complete.    
  8.     
  9. Session 1:    
  10. 13:29:06 HELLODBA.COM>alter system flush buffer_cache;    
  11.     
  12. System altered.    
  13.    
  14. 13:29:11 HELLODBA.COM>-- Transaction 1 begin ---    
  15. 13:29:11 HELLODBA.COM>update t_test1 set lio=(select lio from t_test1 where object_id = 101) where object_id = 102 and (select count(*) from t_test2 t1, t_test2 t2) > 0;    
  16.     
  17. 1 row updated.    
  18.     
  19. 13:29:25 HELLODBA.COM>commit;    
  20.     
  21. Commit complete.    
  22.     
  23. 13:29:25 HELLODBA.COM>-- Transaction 1 end ---    
  24. 13:29:25 HELLODBA.COM>select object_id, lio from t_test1 t where object_id in (101,102);    
  25.     
  26. OBJECT_ID        LIO    
  27. ---------- ----------    
  28.        101          0    
  29.        102          1    
  30.     
  31. 13:29:25 HELLODBA.COM>    
  32.     
  33. Session 2:    
  34.     
  35. 13:29:11 HELLODBA.COM>-- Transaction 2 begin ---    
  36. 13:29:16 HELLODBA.COM>update t_test1 set lio=0 where object_id in (101,102);    
  37.     
  38. rows updated.    
  39.     
  40. 13:29:16 HELLODBA.COM>commit;    
  41.     
  42. Commit complete.    
  43.     
  44. 13:29:16 HELLODBA.COM>-- Transaction 2 end ---   

在這個例子中,我們並發執行了上面兩條語句,但最終得到一個和我們邏輯目標相左的結果。

事務1的SCN早於事務2的SCN,因此它用了一個快照數據(由一致性讀得到的老的數據)來更新了當前數據(由當前模式讀得到的最新的數據)。

我不能說這算不算MVCC的一個缺陷,但它最少已經造成了邏輯混亂。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved