TL;DR | 面試情境模擬 #
👴 面試官:什麼是 ACID?為什麼資料庫需要它?
🧑💻 你:ACID 是資料庫 Transaction 的四個保證:Atomicity(原子性,全做或全不做)、Consistency(一致性,資料永遠符合規則)、Isolation(隔離性,多個 Transaction 互不干擾)、Durability(持久性,寫入後不會消失)。最典型的例子是轉帳:A 扣錢和 B 加錢必須同時成功,任何一步失敗就全部回滾。
比喻:轉帳的四個保命符 #
把 A 轉 1000 元給 B 的操作:
1. A 的帳戶 -1000
2. B 的帳戶 +1000
沒有 ACID,可能發生:
- 步驟 1 成功,步驟 2 失敗 → A 的錢消失了
- 兩筆操作同時進行,讀到中間狀態 → 帳目亂掉
- 系統斷電 → 寫入的記錄不見了
四個屬性詳解 #
A — Atomicity 原子性 #
Transaction 是不可分割的最小單位,要嘛全部成功,要嘛全部失敗(Rollback)。
BEGIN TRANSACTION
UPDATE accounts SET balance = balance - 1000 WHERE id = 'A'
UPDATE accounts SET balance = balance + 1000 WHERE id = 'B'
COMMIT
-- 如果第二步失敗,第一步也會自動回滾
C — Consistency 一致性 #
Transaction 前後,資料都必須符合所有約束規則(如外鍵、CHECK constraint、業務邏輯)。
例如「帳戶餘額不能為負數」是一個規則,ACID 保證 Transaction 結束後這個規則依然成立。
I — Isolation 隔離性 #
多個 Transaction 同時執行時,互相看不到對方未提交的資料。就像每個人在自己的包廂裡用餐,不知道其他包廂發生了什麼。
隔離級別從低到高:Read Uncommitted → Read Committed → Repeatable Read → Serializable(詳見隔離級別篇)
D — Durability 持久性 #
一旦 Transaction COMMIT,資料就永久寫入,即使系統崩潰也不會消失。靠 WAL(Write-Ahead Log) 實現:先把變更寫進日誌,再更新磁碟。
哪些資料庫保證 ACID? #
| 資料庫 | ACID 支援 | 備註 |
|---|---|---|
| PostgreSQL | 完整 | 業界最嚴格的 ACID 實作 |
| MySQL(InnoDB) | 完整 | MyISAM 引擎不支援 |
| SQLite | 完整 | 單檔 DB,嵌入式常用 |
| MongoDB | 部分 | 4.0 後支援多文件 Transaction |
| Redis | 部分 | MULTI/EXEC 有原子性但非完整 ACID |
💡 面試官可能會追問 #
Q1:ACID 和 BASE 有什麼差別? #
BASE(Basically Available, Soft state, Eventual consistency)是 NoSQL 的設計哲學,犧牲強一致性換取高可用性和效能。
- ACID:強一致性,適合金融、訂單等不能出錯的場景
- BASE:最終一致性,適合社群媒體、推薦系統等可以短暫不一致的場景
Q2:什麼是 Phantom Read? #
在同一個 Transaction 中,兩次相同的查詢結果不同——因為另一個 Transaction 在中間 INSERT 了新資料。只有最高隔離級別 Serializable 才能完全防止 Phantom Read。
Q3:資料庫如何實作 Rollback? #
透過 Undo Log:每次修改資料之前,先把原始值記錄在 Undo Log 裡。如果 Transaction 失敗,就根據 Undo Log 把資料還原回去。