關聯式資料庫事務特性
ACID,是指資料庫管理系統(DBMS)在寫入或更新資料的過程中,為保證事務(transaction)是正確可靠的,所必須具備的四個特性:原子性(atomicity,或稱不可分割性)、一致性(consistency)、隔離性(isolation,又稱獨立性,主要針對事務)、持久性(durability)。
在資料庫系統中,一個事務是指:由一系列資料庫操作組成的一個完整的邏輯過程。例如銀行轉帳,從原帳戶扣除金額,以及向目標帳戶添加金額,這兩個資料庫操作的總和,構成一個完整的邏輯過程,不可拆分。這個過程被稱為一個事務,具有 ACID 特性。
資料來源:維基百科 - ACID
四大特性
原子性(Atomicity):一個事務中的所有操作,需要全部完成,亦或者全部不完成,不會結束在中間某個環節。transaction 在執行過程中發生錯誤,會被 Rollback 到 transaction 開始前的狀態,就像這個事務從來沒有執行過一樣。即,transaction 不可分割、不可約簡。
一致性(Consistency):在事務開始之前和事務結束以後,資料庫的完整性沒有被破壞。代表寫入的資料必須完全符合所有的預設數據完整性、資料庫等。
事務隔離(Isolation):資料庫允許多個併發事務同時對該資料庫數據進行讀寫和修改的能力,隔離性可以防止多個事務併發執行,因為交叉執行所導致的數據的不一致。
持久性(Durability):事務處理結束後,對數據的修改就是永久的,即便系統故障也不會遺失。
事務隔離 (Isolation)
事務隔離本身的意義可以防止多個事務併發執行時由於交叉執行而導致數據的不一致。
他有四種類型的 Isolation
未提交讀(Read uncommitted)
A 資料更新但未確認資料,B 事務不能更新只能讀取,直到 A 資料 commit,確保事務更新資料不會有問題。
存在問題:
- 髒讀(Dirty Read)- 可能讀到未提交的資料
- 不可重複讀(Non-repeatable Read) - 同一筆資料,前後讀取結果不一樣
- 幻讀(Phantom Read) - 查詢範圍內的記錄數量改變了
提交讀(read committed)
A 事務更新前,其他事務不能進行讀該資料
解決問題: 髒讀
存在問題:
- 不會讀到未提交的資料
- 不可重複讀
- 幻讀
使用場景:
不需要在事務期間鎖住讀取的資料,效能好,大多數 OLTP (Online Transaction Processing) 應用的預設選擇,如:一般網站應用程式、電商下單流程、社交媒體貼文留言、CRM 系統
可重複讀(repeatable read)
讀取中資料會被鎖定,確保同一筆事務中的讀取資料必須相同
解決問題: 髒讀 + 不可重複讀
存在問題:
- 幻讀
使用場景:
需要保證讀取一致性的業務,如:財務報表生成、資料批次處理、對帳作業、數據分析任務串行化(Serializable)
A 事務讀取時,B 事務更新要排隊;A 事務更新時,B 事務讀取與更新都需要排隊
解決問題: 髒讀 + 不可重複讀 + 幻讀
特點:
- 完全隔離,最安全
- 效能最差,並發度最低
使用場景:
關鍵金融交易、強一致性需求,如:銀行轉帳、庫存扣減、座位預訂系統、發票編號生成
主流資料庫預設隔離級別
PostgreSQL
預設: Read Committed
特色: 即使設定為 Repeatable Read,也能避免幻讀(透過 MVCC 實作)
MySQL (InnoDB)
預設: Repeatable Read
特色: 透過 Next-Key Lock 機制,也能在此級別避免大部分幻讀情況
Oracle
預設: Read Committed
特色: 不支援 Read Uncommitted,只支援 Read Committed 和 Serializable
SQL Server
預設: Read Committed
可選: 還提供 Snapshot Isolation(類似 MVCC 的實作)
SQLite
預設: Serializable
特色: 因為是嵌入式資料庫,預設採用最嚴格的隔離
MariaDB
預設: Repeatable Read(與 MySQL 相同)
特色: 行為與 MySQL InnoDB 基本一致