本文旨在向您介紹數據一致性的概念,以及 DB2 在單用戶和多用戶數據庫環境中用來維護數據一致性的各種機制。本教程還將幫助您為應對 DB2 10.1 基礎認證考試(考試 610)的第 6 部分而做準備。
正在考慮獲得 IBM Certified Database Associate(DB2 10.1 基礎認證)?那您就來對了地方。這個 DB2 10.1 基礎認證準備系列 旨在介紹參加 DB2 10.1 基礎認證考試(考試 610)之前必須了解的所有主題。即使您不打算馬上參加認證考試,本系列中提供的信息也可以幫助您了解 DB2 10 for z/OS? 和 DB2 10.1 for Linux?, UNIX?, and Windows? 中的新特性和功能。
您沒有看到正在尋找的?您可以查看 DB2 9 基礎認證 730 準備系列 中的 DB2 9 。
關于本教程
在 DB2 10.1 基礎認證考試(考試 610)中,有 13% 的內容旨在測試您對一些機制(有關 DB2 用來允許多個用戶和應用程序在不影響數據一致性的情況下與進行交互的機制)的了解。組成考試的這一部分的問題旨在評估:
- 您能夠識別在給定情況下應該使用的隔離級別。
- 您能夠識別 DB2 鎖的特征。
- 您能夠列出可以為其獲得鎖的對象。
- 您能夠識別影響鎖的因素。
本教程旨在介紹數據一致性的概念,以及 DB2 用于在單用戶和多用戶數據庫環境中維護數據一致性的兩個重要機制:隔離級別和鎖。本教程是由 6 部分組成的系列教程中的第 6 部分,您可以使用本教程來準備 DB2 10.1 基礎認證考試(考試 610)。
目標
在本教程中的材料涵蓋了 DB2 10.1 基礎認證考試(考試 610)的第 6 部分的目標。
在完成本教程之后,您應該能夠:
- 識別影響鎖的因素。
- 列出可以在其上獲得鎖的對象。
- 適當地使用 LOCK TABLE 語句。
- 識別 DB2 鎖的特征(在所有平臺上共享的常用鎖)。
- 識別在給定情況下應該使用的隔離級別。
- 知道如何以及何時使用當前已提交 (CC) 的語義。
先決條件
要理解本教程所提供的一些內容,您應該熟悉下列術語:
- 結構化查詢語言 (Structured Query Language, SQL):一種用來在關系數據庫中定義對象和操縱數據的標準化語言。
- 對象:數據庫中可以用 SQL 創建或操縱的任何東西(例如,表、視圖、索引和包等)。
- 表:一種邏輯結構,用來將數據表示為有固定列數的無序行的集合。每個列都包含一組值,列中所有的值都具有相同的數據類型。列的定義組成了表結構,而行包含實際的數據。
- 記錄:表中一行的存儲表示。
- 字段:表中一列的存儲表示。
- 值:具體的數據項,位于數據庫表中行與列的每個交叉點上。
- DB2 優化器:SQL 預編譯器的一個組件,它通過對幾個不同訪問計劃的執行成本進行建模并選擇預計成本最低的計劃,為數據操縱語言 (Data Manipulation Language, DML) SQL 語句選擇一個訪問計劃。
系統需求
您不需要 DB2 的副本也可以順利完成本教程,但是,如果您可以訪問一個 DB2 數據庫,您就能夠測試本教程所展示的一些命令和概念。
您可以從 IBM DB2 Express-C 的一個免費版本。
數據一致性
理解數據一致性
為了理解 DB2 如何嘗試在單用戶和多用戶數據庫環境中維護數據一致性,您必須先了解數據一致性是什么。此外,您還必須能夠識別讓數據庫進入不一致狀態的事件類型。那么到底什么是數據一致性?回答這個問題的最佳方法是研究示例。
假定某公司擁有多家連鎖飯店,公司用一個數據庫來跟蹤每家飯店中的庫存等信息。數據庫包含每家連鎖飯店的庫存表。每當一家飯店收到或用掉一部分貨物時,就會更新相應的庫存表?,F在,假定將一箱咖啡從一家飯店(其咖啡庫存量充足)調配到另一家飯店(其咖啡剛剛用完)。為了準確地反映這一次庫存調配,在接收方飯店的庫存表中所存儲的咖啡瓶數的值需要有所增加,而調出方飯店的表中所存儲的咖啡瓶數的值需要有所減少。如果用戶增加了接收方飯店的庫存表中的咖啡瓶數的值,但沒有減少調出方飯店庫存表中的咖啡瓶數的值,那么數據庫中的數據就會不再一致。此時所有連鎖店的咖啡的總瓶數不再準確,調出方飯店的咖啡瓶數也不再準確。
在單用戶環境中,如果用戶沒有進行必要的更改(如前面的示例),或者如果在用戶或應用程序進行更改的過程中系統崩潰了,又或者如果應用程序過早地終止,那么數據庫中的數據都會變得不一致。在多用戶環境中,當幾個用戶或應用程序嘗試同時訪問相同的數據時,也可能會發生不一致。例如,在剛剛介紹的場景中,如果一個用戶查詢數據庫以獲得接收方飯店的咖啡瓶數,同時另一個用戶在更新兩家飯店的庫存表,以反映有一箱咖啡從一家飯店轉移到另一家飯店,在更新被提交之前,查詢將會錯誤地顯示沒有剩余的咖啡。
事務、隔離級別和鎖
事務
DB2 用于保持數據一致性的主要機制是事務。事務(也稱為工作單元)是一種將一個或多個 SQL 操作組合成一個單元的可恢復序列,通常位于應用程序中。事務的啟動和終止定義了數據庫內的一致性點;要么將一個事務中執行的所有操作的結果都應用于數據庫,并使其成為永久性的(已提交),要么完全撤消(已回滾)它們,并且數據庫回到事務啟動之前的狀態。在單用戶環境中,事務是按順序運行的,并且不必與其他并行運行的事務競爭。但在多用戶環境中,事務通常是同時運行的。因此,每個事務都有可能干擾正在運行的任何其他事務;要控制所允許的總干擾數量,就需要使用另一個機制:隔離級別。
有可能彼此干擾的事務被稱為是交錯的(或并行的)事務,而彼此完全隔離的事務被稱為是可序列化的 事務,這意味著,同時運行它們的結果與按順序(一個接一個地)運行它們的結果將沒有什么不同。在理想的情況下,每個事務都應該是可序列化的。為什么呢?假設一個銷售人員和會計師在同一時間使用相同的數據庫。現在,假設銷售人員在錄入 X 公司的訂單(以生成報價),但沒有提交其錄入條目。同時,會計師將查詢數據庫,獲得所有未支付訂單的列表,檢索 X 公司的新訂單,并生成一個賬單?,F在,假設負責 X 公司的銷售人員決定不下訂單。因為訂單還沒有發出,所以該銷售人員可以回滾事務,有關訂單的信息會從數據庫中刪除。然而,一個星期后,X 公司收到的賬單中包含這個從未發出的訂單。如果銷售人員的事務和會計師的事務彼此完全隔離(也就是說,事務是序列化的),這種情況就不會發生。無論是銷售人員的事務在會計師的事務開始前完成,還是會計師的事務在銷售人員的事務開始之前完成,在這兩種情況下,X 公司都不會收到賬單。
如果事務不是可序列化的,那么可能出現四種現象:
- 丟失更新:當兩個事務在同一時間讀取相同的數據并且都試圖更新該數據時,會出現這種情況,導致其中一個更新的損失。例如:事務 1 和事務 2 讀取相同行的數據,并根據讀出的原始值為該行計算新的值。如果事務 1 用其新值更新行,而事務 2 在之后更新同一行,那么事務 1 所執行的更新操作都將丟失。
- 臟讀 (Dirty Read):當一個事務讀取尚未提交的數據時,會出現這種情況。例如:事務 1 修改了一行數據,而事務 2 在提交更改之前讀取了已更改的行。如果事務 1 回滾該變更,那么事務 2 將會讀取從未真正存在的數據。
- 不可重復讀取 (Nonrepeatable Read):當一個事務讀取同一行數據兩次,但每次都獲得不同的結果時,就會出現這種情況。例如:事務 1 讀取一行數據,然后事務 2 修改或刪除該行并提交了變更。當事務 1 嘗試重新讀取該行,它會檢索到不同的數據值(如果該行被更新)或發現該行已經不存在(如果該行被刪除)。
- 幻像:當一行數據與某些搜索條件相匹配,但該行在最初不可見時,就會出現這種情況。例如:事務 1 檢索一組滿足某些搜索條件的行,然后事務 2 插入一個新行,該行與事務 1 的查詢的搜索條件相匹配。如果事務 1 再次執行生成原來那一組行的查詢,被返回的將是另一組不同的行。(事務 2 所添加的新行現在將被包含在所生成的這組行中。)