程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> DB2數據庫 >> DB2教程 >> 分布式 DBA: Cursor Stability Isolation Level 的變化:第 2 部分(理解 Currently Committed 行為)

分布式 DBA: Cursor Stability Isolation Level 的變化:第 2 部分(理解 Currently Committed 行為)

編輯:DB2教程

在我的上一篇專欄中,我解釋了在多用戶環境中,隔離級別在防止數據庫出現數據不一致性時所起到的關鍵作用。同時,我也介紹了 Cursor Stability (CS) 隔離級別在 IBM DB2 9.5 實現防止鎖技術前後是如何工作的。在本專欄中,我將介紹 DB2 9.7 引入的 Currently Committed (CC) 的語義,並且我將介紹這些語義是如何實現快速數據訪問和如何增加運行在 CS 隔離級別下的 SQL 語句的數據並發數。

Currently Committed 語義

DB2 9.7 引入了一個新實現的 CS 隔離級別,這個隔離級別能夠使用 CC 語義進一步防止寫操作阻塞讀操作。它的目的是實現一個 CS 語義允許且能避免鎖等待的 CS 隔離級別(類似於 DB2_SKIPDELETED 和 DB2_EVALUNCOMMITTED 注冊表變量的用法 — 見側邊欄,“用於在一些環境中延遲或避免獲取鎖的注冊表變量”)。

通過使用完全防止鎖技術(我的上一個專欄介紹過),只要 DB2 能夠確定所需要的數據已經提交,使用 CC 語義的只讀 SQL 就不會獲得一個鎖。然而,如果 DB2 不確定所需要的數據是否已經提交,運行這個語句的事務將會嘗試獲得問題記錄的鎖。

如果獲得一個鎖後,進程將繼續使用傳統的 CS 隔離級別行為。如果不能獲得一個鎖(由於另一個事務獲取了這個記錄行的 Exclusive 鎖),DB2 將檢查這個由其他事務所保持的鎖,得到關於這個記錄的信息。這個鎖可能包含以下一種(有且只有一種)情況的信息:

沒有信息:表示記錄被鎖,但是還沒有對它作任何操作(即,沒有未提交的修改)

有一個 Uncommitted Insert 標識符: 表示該記錄是新插入的,但還沒有被提交

日志信息:表示該記錄包含未提交數據;這種情況下,日志信息標識了當前保持記錄鎖的事務對記錄的第一次修改的日志記錄

如果這個鎖沒有包含任何信息,這個記錄會以獲得目標鎖的方式處理。如果這個鎖包含了一個 Uncommitted Insert 標識符,那麼這個記錄會被忽略,因為這個標識符表示這個記錄還沒有被提交。如果這個鎖包含了日志信息,這個信息將被用於從存儲在日志緩存或事務的日志文件中的日志記錄查詢到該記錄的 CC 版本(即,修改前的記錄)。然後,DB2 會使用 Log Sequence Number (LSN) 直接訪問對應的日志記錄(見側邊欄,“DB2 如何確定數據是否已經提交”)。

圖 1 說明了使用 CC 語義的 CS 隔離級別的一個 SELECT 語句是如何查詢記錄的。一定要注意 CC 語義可以應用到 Read Stability (RS) 以及 CS 隔離級別的 SQL 語句上。然而,在 RS 隔離級別上執行時,CC 只支持 DB2_SKIPINSERTED 行為,這種功能不會再引起未提交插入記錄的鎖等待。

圖 1. 在本例中,事務 1 執行了兩個 DML 語句,它會導致一個日志信息及一個 Uncommitted Insert 標識符被寫入 SALES_REP 表的鎖列表。當事務 2 查詢 SALES_REP 表時, CC 語義支持從前一個提交事務的日志記錄中讀取鎖定記錄的數據;Uncommitted Insert 的記錄則不會返回。

分布式 DBA: Cursor Stability Isolation Level 的變化:第 2 部分(理解 Currently Committed 行為)

查看原圖(大圖) 

啟用 Currently Committed 語義行為

在某些環境中用於延遲或避免獲取鎖的注冊表變量

如果事務是並發運行的,可能會發生下面的現象:

DB2_SKIPINSERTED: 允許 CS/RS 掃描忽略未提交插入記錄

DB2_SKIPDELETED: 允許 CS/RS 掃描忽略未提交刪除記錄和索引鍵

DB2_EVALUNCOMMITTED: 允許 CS/RS 掃描對未提交數據應用和執行可預見性評估;同時允許掃描忽略未提交的刪除記錄。實際上,它將掃描當作一個 Uncommitted Read,直至它發現一個匹配的記錄,這時它可能需要鎖定記錄以保證只有提交的數據才會被處理/返回。

默認情況下,使用 DB2 9.7 創建的新數據庫是啟用 CC 語義的。對於升級到 DB2 9.7 的現有數據庫,通過將所轉換的數據庫的配置參數 cur_commit 賦值為 ON 或 AVAILABLE 就可以啟用 CC 語義。如果數據庫配置參數 cur_commit 被設置為 ON,CC 語義就會應用到整個數據庫的 CS 和 RS 隔離。如果數據庫配置參數 cur_commit 被設置為 AVAILABLE,DB2 將會把對應的信息存儲到鎖中,然後執行支持 CC 語義所需要的額外的日志信息(保證所修改記錄的日志數據包含了完整未提交版本),但是 CC 語義行為將必須在應用中逐一啟用。這可以通過使用 CONCURRENTAccessRESOLUTION USE CURRENTLY COMMITTED 選項綁定一個嵌入式 SQL 應用到數據庫實現,或者通過指定 CLI/ODBC 或 Java 應用的 SQL_ATTR_CONCURRENT_Access_RESOLUTION 連接屬性實現。

注意使用 CC 語義需要增加日志空間來存儲被定義為 DATA CAPTURE NONE 的表的更新操作。這個額外的空間被用於記錄當前事務對一個數據記錄的第一次更新操作;這個數據會被用於查詢記錄行的最新提交鏡像。

結束語

DB2 如何確定數據是否已經提交

所示數據記錄和索引條目都有一個 “標記” 字節,它包含了一個 “Possibly UNCommitted (PUNC)” 位。如果 PUNC 未設置,數據的記錄/索引條目就一定會被提交;否則提交狀態就是未知的。

頁包含了一個 “pageLSN”,它標識了與頁最新修改相對應的日志記錄的 LSN。如果 pageLSN 比數據庫的 commitLSN 或一個表的 readLSN 舊,那麼行/鍵就保證被提交;否則提交就是未知的。

保持數據的一致性和完整性,同時允許多個事務同時訪問相同的數據,這是一個難題,特別是在多用戶環境中。事務、隔離級別和鎖有助於保持數據的一致性,而 CS 隔離級別的使用越來越多,因為它能夠在防止髒讀取(即一個事務讀取還沒有提交的數據)的同時實現最大的並發數。在 DB2 9.7 之前的版本中,使用這種隔離級別可能會由於鎖待而增加響應時間。

CC 語義提供了一種全新實現的 CS 隔離級別,它符合 ANSI 的 CS 隔離級別標准。通過 CC 語義,執行讀和寫操作的事務可以避免未提交插入的鎖等待,同時執行只讀操作的事務在遇到並發事務的未提交的更新/刪除時,不再需要使用鎖來等待一個日志讀取操作。這個行為實際上保證了應用的響應時間不受鎖的影響。

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