Try   HackMD

RDBMS Isolation by triton Ho 讀後筆記

Isolation 中文意思: 隔離
TX: transaction

簡單來說 就是減少 race condition 的機制
Database 為了最大效能 盡可能同時處理多個TX
但如果有兩個TX同時改動相同資料時 RDBMS會讓後來的TX 被blocking 以免發生race condition

race condition

用遊戲的玩法來說 楓之谷 噴了一頂炎盔 兩名玩家只會有一個人先撿起來 不可能一頂炎盔 會同時有兩個一起放入各自的包包

RDBMS

Atomicity

Atomicity 原子性

一個TX中的所有操作 只會有全部完成 或是全部不完成 不會結束在中間某個環節 TX執行過程當中發生錯誤 DB會自動發生Rollback 到TX前的狀態 TX 不可分割 不可約簡

Consistency

Consistency(一致性)

TX開始前與結束後 資料庫的完整性沒有被破壞 表示寫入的資料必須完全符合資料庫設定的所有預設約束 觸發器 級聯回滾

級聯回滾: 一個TX失敗引起的所有TX隨之失敗 要能各自Rollback

Isolation

Isolation(隔離性)

資料庫允許多個TX同時對數據進行讀寫和修改的能力 隔離性 可以防止多個TX並發執行時 對同筆資料交叉執行而導致數據的不一致

事務隔離分為不同級別
由最低級依序->最高級

  • Read uncommitted(未提交讀)
  • Read committed(提交讀)
  • Repeatable read(可重複讀)
  • Serializable(串行化)

未提交讀

Read uncommitted 最低級別的隔離級別 允許髒讀(ditry read) TX 與 TX之間可以看見尚未commit的修改

提交讀

Read committed 基於鎖機制並發控制DBMS需要對選定對象的寫鎖一直保持到TX的結束, 但是讀鎖在SELECT操作完就馬上釋放(因此不可重複讀 現在可能會發生) 也不要求範圍鎖

可重複讀

Repeatable reads 基於鎖機制並發控制DBMS需要對選定對象的讀鎖(read locks)寫鎖(write locks) 一直保持到TX結束 但不要求範圍鎖 有可能發生幻影讀

可串行化

SERIALIZABLE 最高的隔離級別 基於鎖機制並發控制DBMS,可串行化要求對象在讀鎖 寫鎖 直到TX結束後才能釋放 在SELECT語句中使用where 描述一個範圍時會獲得一個範圍鎖 可避免幻影讀的現象 當系統探測到併發事務有寫衝突時 只有一個是允許提交

隔離級別 vs 鎖持續時間

"C"-表示鎖會持續到事務提交
"S" –表示鎖持續到當前語句執行完畢

隔離級別 寫操作 讀操作 範圍操作(where)
未提交讀 S S S
提交讀 C S S
可重複讀 C C S
可序列化 C C C

髒讀 (dirty reads)

TX1 讀取數據並修改數據 TX2 進行讀取數據時讀到了尚未commit的數據 TX1將數據Rollback後 TX2讀取錯誤的數值

Mysql, Oracle, PostgreSql 標準設定都不會發生Dirty Read

不可重複讀 (non-repeatable reads)

TX1 在同一個TX當中發出兩次讀取資料庫的請求 select * from user where id = 1;
TX2 在TX1讀取的過程中(第一次讀取與第二次讀取的中間) 進行了資料庫修改 導致 TX1讀取select *from user where id =1 時 資料不一致

故事: 小明購買機票,查詢價格時200塊一張,當小明按下交易的按鈕時 航空公司決定漲價了,導致小明買到一張300塊的機票

幻影讀 (phantom read)

TX1 在同一個TX發起兩次讀取資料庫的請求並限制條件 select * from user.balance > 1000
TX2 在TX1發起的過程中insert一筆資料 balance>1000的user
TX1 在讀取資料庫的第二次請求會發現多了一筆資料 此現象稱為幻影讀

不可重複讀的重點在於修改
同樣的條件下 讀取過的資料再次讀取時發生改變

幻影讀的重點在於新增或刪除
同樣條件下第一次與第二次的筆數不同

Durability

Durability(持久性)

事務處理結束後,對數據的修改就是永久,即使系統故障也不會丟失

SX lock vs MVCC

SX lock

  • Mysql
  • MSSQL

機制

  1. 在database當中 每個record都有其SX lock(別名: Readers-writer lock)
  2. S lock 對應資料的讀取 X lock對應資料的改動
  3. 所有由TX擁有的lock 在TX結束時會自動釋放並歸還( S Lock視 Isolation level 決定歸還時間)
  4. S lock 能同時發給多個TX 所以同時間能有多個TX進行讀取同一塊資料
  5. 發行 X lock時, Record必須沒有其他的 lock(不管是 S還是X)。直到該 X lock結束之前,該 Record都不能發行其他的 lock
    – 所以直到該 TX結束,該 Record都不能被其他 TX讀取/改動

MVCC

  • PostgreSQL
  • Oracle

Multiversion concurrency control 多版本並發控制

  1. 可以理解為git模式 每次insert/update都會為該Record增加額外的版本
  2. 每個record的每個版本都會有時間(相似東西) 讓RDBMS知道哪份版本才是最新的
    • record太舊的版本會被資料庫自動刪除
  3. MVCC 資料庫的record只有 X lock 而沒有 S lock
  4. MVCC 在讀取時會讀取該record最新的commmited版本 所有自動解決的Dirty Read
  5. 因為只有WRITE-WRITE conflict 所以MVCC的Read永遠不會被阻擋

實務建議8

  • 在超高流量的搶票系統當中 別用insert做conflict collision
  • Bad idea:
    • insert into ticket.. 依靠