🔒資料庫系統的鎖定機制在各情境下存在的必要性
在資料庫系統中,鎖定機制(Database Locking) 是確保資料一致性的關鍵手段。當多個使用者或交易同時存取資料庫時,若沒有妥善的鎖定機制,極可能造成資料錯誤與不一致。本文將透過兩個經典案例,說明為何鎖定在不同情境下是必要的。
🔒資料庫系統的鎖定機制在各情境下存在的必要性
在資料庫系統中,鎖定機制(Database Locking) 是確保資料一致性的關鍵手段。當多個使用者或交易同時存取資料庫時,若沒有妥善的鎖定機制,極可能造成資料錯誤與不一致。本文將透過兩個經典案例,說明為何鎖定在不同情境下是必要的。

💵案例一「銀行ATM交易」
銀行ATM交易中,假設你的帳戶有1000元,此時有兩個並發操作:
操作A:你在ATM提款500元
操作B:你的配偶同時在另一台ATM提款600元
如果沒有鎖定機制,可能發生:
-
A和B同時讀取餘額:都看到1000元
-
A計算:1000–500=500,準備寫入
-
B計算:1000–600=400,準備寫入
-
結果:最後寫入的覆蓋前一個,帳戶餘額可能是500或400
但實際上兩筆提款都成功了(實際應該拒絕其中一筆)
✨ 解決方案:
當操作A開始執行轉帳時,對該帳戶加上「排他鎖」,此時:
🔹 操作B無法對同一帳戶進行提款(需等待A完成)
🔹 餘額查詢可以進行,但會讀取到「鎖定前的狀態」或「交易完成後的狀態」
(取決於資料庫的隔離級別設定)
這確保了帳戶餘額的正確性,避免超額提領。
●🛒案例二 「電商購物時的庫存控制問題」:
某商品剩餘庫存為1件,消費者A和B幾乎同時點擊「立即購買」:
📌 情境一:沒有鎖定機制(會超賣)
-
A的請求:查詢庫存 → 顯示剩餘1件 → 可以購買
-
B的請求:查詢庫存 → 顯示剩餘1件 → 可以購買
-
A確認訂單 → 扣減庫存:1–1=0
-
B確認訂單 → 扣減庫存:1–1=0
-
結果:兩筆訂單都成立,但實際只有1件商品(超賣!)
✨ 解決方案一:悲觀鎖(適合高競爭商品,如秒殺活動)
當A開始結帳流程時:
-
對該商品庫存加上「排他鎖」(SELECT … FOR UPDATE)
-
確認庫存足夠 → 扣減庫存 → 建立訂單 → 釋放鎖
-
B的請求必須等待A完成,此時查詢到庫存為0,顯示「已售完」
-
優點:絕對不會超賣
-
缺點:併發性能較低,等待時間長
✨ 解決方案二:樂觀鎖(適合一般商品)
不先鎖定,而是在最後更新時檢查:
-
A讀取:庫存=1(版本號=v1)
-
B讀取:庫存=1(版本號=v1)
-
A更新:WHERE 庫存=1 AND 版本=v1,成功 → 庫存變0(版本號=v2)
-
B更新:WHERE 庫存=1 AND 版本=v1,失敗(版本已改變)→ 提示「商品已售完」
-
優點:高併發性能好
-
缺點:衝突時需要重試
📍 實務補充:
🔹「加入購物車」通常不鎖定庫存(否則放著不買會佔用庫存)
🔹真正的鎖定發生在「提交訂單」或「進入結帳頁面」時
🔹大型電商通常設定「購物車保留時間」(如15分鐘),超時自動釋放
經由上面兩種案例,我們可以知道資料庫併發在實務上的應用。
🏹資料庫併發控制的目標:
👉解決當多個使用者或交易試圖同時存取和更改資料時可能發生的問題
🔎為了解決這種併發導致的資料不一致性,來源提出了資料庫鎖定(Database Locking)作為解決方案:
1.排他鎖(又稱寫入鎖定或寫鎖)主要用於資料庫的寫入、更新或編輯操作。
💡在排他鎖定存在期間,其他交易無法對同一資料取得排他鎖或共享鎖
2.共享鎖(又稱讀取鎖定或讀鎖)主要用於資料庫的讀取操作。
💡一旦共享鎖定被取得,沒有人可以對該帳戶取得排他鎖定,因此無法更新資料
🎯結語
🛡️共享鎖定和排他鎖定完全是彼此的對立面。它們之間的衝突是確保資料一致性的核心機制。
引入共享鎖定和排他鎖定是為了確保系統的一致性 (consistency),即使這種機制會犧牲併發性作為代價,但對於銀行這種高度講求一致性的產業來說資料一致性更為重要。
如果這篇文章對你有幫助,歡迎按下「👏」或追蹤我的 instagram 或是threads 帳號,我將持續分享更多 Kubernetes 、CI/CD、雲端服務、後端開發、資料工程的實戰心得!
메타데이터
- post_id
- 45289f7dfd4f
- slug
- 資料庫系統的鎖定機制在各情境下存在的必要性-45289f7dfd4f
- url
- https://medium.com/@codeseeker2024/%E8%B3%87%E6%96%99%E5%BA%AB%E7%B3%BB%E7%B5%B1%E7%9A%84%E9%8E%96%E5%AE%9A%E6%A9%9F%E5%88%B6%E5%9C%A8%E5%90%84%E6%83%85%E5%A2%83%E4%B8%8B%E5%AD%98%E5%9C%A8%E7%9A%84%E5%BF%85%E8%A6%81%E6%80%A7-45289f7dfd4f
- canonical_url
- https://medium.com/@codeseeker2024/%E8%B3%87%E6%96%99%E5%BA%AB%E7%B3%BB%E7%B5%B1%E7%9A%84%E9%8E%96%E5%AE%9A%E6%A9%9F%E5%88%B6%E5%9C%A8%E5%90%84%E6%83%85%E5%A2%83%E4%B8%8B%E5%AD%98%E5%9C%A8%E7%9A%84%E5%BF%85%E8%A6%81%E6%80%A7-45289f7dfd4f
- author_url
- https://medium.com/@codeseeker2024
- status
- ok
- fetched_at
- 2026-07-14 01:40:41