在這篇論文之前 — 它所降落的世界
1976 年之前,大家已經知道對共用資料的並行讀寫會出事。兩支程式各自把共用變數 x 加 1,若兩者都在對方寫入前先讀了 x,其中一次更新就會不見;又或者一筆交易把 100 美元從帳戶 1 轉到帳戶 2,另一筆卻讀到轉帳前的帳戶 1 與轉帳後的帳戶 2,看到一個從未存在過的資料庫狀態。當時已知用鎖可以避免這些狀況,但設鎖與解鎖是應用程式自己的事,系統幾乎沒有告訴程式該鎖哪些東西、又該鎖到什麼時候。既沒有一個公認的名稱來指涉鎖所要保護的工作單位,也沒有對並行執行明確寫下的正確性準則,更沒有任何鎖定規則被證明達成了這個準則。當時的商用系統,例如 IBM 的 IMS/VS 與 UNIVAC 的 DMS 1100,各自有一套臨時拼湊的鎖定行為,Gray 的鎖定粒度論文最後一節正是在整理這些做法。
術語 — 依本篇論文的用法
- Two-phase locking
- 一套包含三條規則的鎖定紀律:存取每個 entity 前先取鎖、存取完成後才放鎖、釋放任何一把鎖之前先取得所有需要的鎖。遵守它就能讓執行等價於這些交易的某個序列執行。
- Serializability
- 並行執行的正確性目標:其效果必須與這些交易的某個非交錯序列執行相同。由於每筆交易單獨執行時就會保持一致性,serializable 的執行自然也保持一致性。
- Phantom 問題
- 在一筆依欄位值取回紀錄的交易的兩次操作之間,某一列忽然出現或消失,即使雙方都遵守 two-phase locking 仍破壞 serializability。解法是把該次取回真正查詢過的資料項也鎖住,例如索引項目或 end-of-table 標記。
- Predicate lock
- 以欄位值上的述詞(例如 Location = 'Napa')而非以識別碼來指涉一組紀錄的鎖。要授予這種鎖,必須先確認同一張表上沒有其他交易持有與之互相可滿足的 predicate lock。
- Intention lock
- 設在粗粒度 entity 上的弱鎖(IS 或 IX),用來警告其他交易:持有者在其後代上持有或將持有細粒度的 S 或 X 鎖。同一 entity 上 IS 與 X 衝突、IX 與 S 及 X 皆衝突;SIX 則結合了對該 entity 的共享存取與對後代上 X 鎖的權利。
- Degrees of consistency
- Gray 提出的四級鎖定協定階層,差別在於鎖的持有時間:degree 0 只在更新期間持有 X 鎖,degree 1 持有到提交,degree 2 再加上短期讀鎖,degree 3 再把讀鎖延長因而符合 two-phase locking。這些就是 SQL 後來所稱的隔離等級。
- Compensating transaction
- 在某筆交易已經提交之後,另外執行一筆用來改變其效果的交易,因為提交等於放棄了丟棄更新的權利。1981 年的論文似乎是最早引入這個概念的文獻,後來由 sagas 進一步一般化。
- Snapshot isolation
- 一種多版本協定:交易讀取每個 entity 中提交時間戳不大於自身起始時間戳的最大版本,提交時若它寫過的任一 entity 曾被更晚提交的交易更新過就 abort,此即 first-writer-wins 規則。它禁掉了 ANSI 三種現象,卻仍容許非 serializable 的執行。
- Paxos Commit
- 一種 atomic commit 協定:每個 resource manager 是否進入 prepared 狀態,交由它自己在一組 acceptor 上執行的 Paxos instance 決定,而這些 acceptor 取代了備援 transaction manager 的角色。改成對 prepare 而非 commit 達成共識,就把 three-phase commit 的兩輪共識併成一輪,省下一個訊息延遲。