基礎總覽
ACID:
- 原子性(Atomicity)
- 一緻性(Consistency)
- 隔離性(Isolation)
- 持久性(Durability)
髒讀:讀到了其他事務未送出的資料;
不可重複讀:同一事務内,兩次相同的查詢傳回了不同的結果;
幻讀:主要針對于新增和删除,在A對一批資料進行修改後,未送出時,B事務新增了一條記錄,導緻A好像少修改了一條資料一樣;
隔離級别 | 髒讀 | 不可重複讀 | 幻讀 |
讀未送出 | 會 | 會 | 會 |
讀已送出 | 不 | 會 | 會 |
可重複讀(預設) | 不 | 不 | 會 |
串行化 | 不 | 不 | 不 |
事務實作原理
基本概念
- LBCC:基于鎖的并發控制;
- MVCC:多版本的并發控制;
MVCC相關概念
MVCC增加了兩個隐藏列,一個記錄事務ID(DB_TRX_ID),一個記錄復原指針(DB_ROLL_PT);
- DB_TRX_ID:事務ID,依次遞增;
- DB_ROLL_PT:指向上一個版本undo log的指針,會形成undo log history list;
- Undo log:事務的備份日志,insert和update都會産生undo log;
- Read view:一緻性視圖,MVCC下,每次讀都會産生read view;
- Purge:undo log的清理線程,按照配置政策來清理undo log;
- m_ids:目前活躍的事務ID清單;其中,最大的ID是max_id,最小的min_id;
- DML:SELECT、UPDATE、INSERT、DELETE;
- DDL:比DML要多,主要的指令有CREATE、ALTER、DROP等;
read view讀取原則(拿目前事務的事務ID來比較):
- 小于min_Id 資料可見
- 大于max_Id 資料不可見
- 在min_Id和max_Id之間
- 若row tx-id在數組中,代表是由還沒送出事物生成的,不可見
- 若row tx-id不在數組中,代表是由已經送出的事物生成,可見
(如果資料不可見,會根據版本鍊的DB_ROLL_PT指針找到上一條資料,直到找到可見的資料)
快照讀:
RR級别下,普通的select就是快照讀;
目前讀:
select…lock in share mode(讀鎖)
select…for update(悲觀鎖)
update,delete,insert
以上都是目前讀;
間隙鎖(record lock) + 行鎖(gap lock) = 臨鍵鎖(next key lock)
- 臨鍵鎖是左開右閉的區間;
- 加鎖的基本機關是臨鍵鎖;
- 唯一索引 等值查詢,臨鍵鎖更新為行鎖;
- 索引等值查詢 不存在的值,向右查詢第一個不滿足需求的值,臨鍵鎖降級為間隙鎖;
- 索引範圍查詢會産生臨鍵鎖;
基礎概念介紹完了,下面開始進入正題:
讀未送出
- 不加鎖,性能最好;
讀已送出(RC)
- 每次select都會生成一次新的read view;
- RC級别下,不會加間隙鎖;
可重複讀(RR)
- 一直沿用第一次select産生的read view,目前事務session生效;
- select不加鎖時,是快照讀,不會産生幻讀;
- update沒有命中索引時,會鎖全表;
- insert隻加意向鎖(隐式鎖),隻有發生沖突時才加鎖;
- 快照讀與目前讀 混合使用時,會産生幻讀;
串行化
- 都是悲觀鎖;