← 所有文章2026.06.20 · CS 411 · 資料庫系統

Transactions、Serializability 與 Isolation:推理並行寫入

從 ACID、schedule 與 precedence graph,一路理解 anomaly、isolation level、lock 與雙 session 實驗。

Concurrency 難在每個 transaction 單獨看都正確,交錯執行後卻可能得到錯誤結果。

ACID 是四種責任

  • Atomicity: 要嘛全部 commit,要嘛完全沒有 effect。
  • Consistency: 合法 transaction 把資料庫從一個合法狀態帶到另一個。
  • Isolation: Concurrent execution 遵守宣告的隔離 contract。
  • Durability: Commit 的結果能承受系統承諾涵蓋的 failure。

資料庫不會自動發明 consistency rule;合法狀態仍要由 constraint 與 transaction logic 定義。

Schedule 與 conflict

Schedule 是多個 transaction read/write 的交錯順序。兩個 operation 同時符合以下條件才 conflict:操作同一個 item、來自不同 transaction,而且至少一個是 write。

T1: read(A)  write(A)
T2:          read(A)  write(A)

Precedence graph 以 transaction 為 node。若 Ti 的 conflict operation 先於 Tj,加入 Ti → Tj。Graph 有 cycle,就不是 conflict-serializable schedule。

白話來說: Graph 在問這些 transaction 能不能排成一個一致的「誰先發生」順序。Cycle 代表每個 transaction 都必須排在另一個前面,無法成立。

常見 anomaly

Anomaly 意外改變的內容
Dirty read 讀到另一個 transaction 尚未 commit 的資料
Non-repeatable read 同一 row 再讀一次,得到不同 committed value
Phantom 同一 predicate 再查一次,row set 改變
Lost update 一次 write 覆蓋另一個 transaction 的成果
Write skew 各自檢查都通過,合在一起卻破壞 invariant

不同 database 雖然使用相似 isolation level 名稱,實際 guarantee 不完全相同。不能只背 SQL standard 表格,還要確認目標產品。

Lock 與 MVCC 解決不同部分

Shared/exclusive lock 協調 conflict access。Two-phase locking 在 growing phase 取得 lock,在 shrinking phase 釋放。Strict 2PL 把 write lock 保留到 commit,可避免其他 transaction 讀取 uncommitted write,也防止 cascading abort。

MVCC 保留 row version,讓 reader 經常不必 block writer。它降低 contention,不代表 write conflict 和所有 anomaly 都消失。

驗證 lost-update defense

開兩個 PostgreSQL session,先建立資料:

CREATE TABLE inventory(product_id integer PRIMARY KEY, quantity integer NOT NULL);
INSERT INTO inventory VALUES (42, 1);

兩邊都執行同一個 atomic statement:

UPDATE inventory
SET quantity = quantity - 1
WHERE product_id = 42 AND quantity > 0
RETURNING quantity;

只有一個 transaction 能成功回傳扣減後的 row。另一個取得 lock 後,會看到 predicate 已不再成立。

從 invariant 選 isolation

不要先決定「全部 serializable」或「read committed 比較快」。先寫下 invariant,構造會破壞它的 interleaving,再選 atomic statement、explicit lock、constraint 或更強 isolation。

複習卡

  • 正確 transaction 仍可能組成錯誤 schedule。
  • Conflict 必須是同 item、不同 transaction,而且包含 write。
  • Precedence graph 有 cycle 就不是 conflict-serializable。
  • MVCC 改善 reader/writer concurrency,不會消除所有 anomaly。
  • Isolation level 名稱無法完全跨產品類比。
  • 從 invariant 與危險 interleaving 開始設計。