mysql
一、 樂觀鎖
和 悲觀鎖
樂觀鎖
和 悲觀鎖
是實現(xiàn)并發(fā)操作的兩種不同的 加鎖思想
础拨,其中:
-
樂觀鎖
假設(shè):操作能成功牌借,不需要事先加鎖,只要在真正提交時驗證本次修改是否可以提交
巩那,如果不可以提交,則重新嘗試更新此蜈。 -
悲觀鎖
假設(shè):操作不能成功即横,需要事先對要更新的數(shù)據(jù)加鎖,操作成功后再釋放鎖裆赵,以便其他線程能獲得鎖东囚。
二、 MVCC
實現(xiàn)思路
MVVC
战授,全名 Multi-Version Concurrency Control
页藻,即:多版本并發(fā)控制
,是 MySQL 的 InnoDB 存儲引擎下植兰,repeatable-read
和 read-committed
隔離級別時事務(wù)的 樂觀鎖
的實現(xiàn)方案份帐。大概的實現(xiàn)思路是:
- 在 InnoDB 的表中增加兩個隱藏字段:
創(chuàng)建版本號
和刪除版本號
。 - 在開啟一個事務(wù)時楣导,生成一個事務(wù)的版本號废境。
- 被操作的數(shù)據(jù),會臨時生成一條新的記錄,這條
臨時記錄
對其他事務(wù)時不可見的(事務(wù)的隔離性原則)噩凹。 - 如果事務(wù)執(zhí)行成功朦促,會將
更新后的數(shù)據(jù)
和事務(wù)的版本號
更新到真實的記錄上,同時刪除臨時記錄栓始。 - 因此,在
MVCC
中血当,其實是不存在鎖
的幻赚,既避免了爭鎖等問題,又保證了并發(fā)操作臊旭。
三落恼、 MVCC
下的 CURD
1. insert
將當(dāng)前的事務(wù)版本號作為數(shù)據(jù)的創(chuàng)建版本號。
2. delete
將當(dāng)前的事務(wù)版本號作為數(shù)據(jù)的刪除版本號离熏。
3. update
- 基于要刪除的行佳谦,復(fù)制出一個臨時行。
- 將當(dāng)前事務(wù)的版本號設(shè)置為要刪除數(shù)據(jù)的刪除版本號滋戳。
- 將當(dāng)前事務(wù)的版本號設(shè)置為臨時行的創(chuàng)建版本號钻蔑。
- 事務(wù)提交時,用臨時行替換要刪除的行奸鸯。
4. select
同時滿足一下兩個條件的數(shù)據(jù)咪笑,會作為查詢結(jié)果返回:
- 條件一:數(shù)據(jù)的創(chuàng)建版本號小于等于事務(wù)版本號。即:在事務(wù)開始前娄涩,數(shù)據(jù)是存在的窗怒。
- 條件二:數(shù)據(jù)的刪除版本號未定義或者大于事務(wù)版本號。即:在事務(wù)開始前蓄拣,數(shù)據(jù)還沒被刪除扬虚。
四、MVCC
優(yōu)缺點
1. 優(yōu)點:
- 因為
MVCC
中并沒有使用鎖球恤,從而避免了鎖
的資源浪費和爭鎖
辜昵、死鎖
等問題。 - 使用兩個隱藏的版本號和事務(wù)版本號巧妙的解決了
不可重復(fù)讀
的問題碎捺。 -
讀
不加鎖路鹰,速度快。 -
讀
和寫
不沖突收厨。
2. 缺點:
- 存儲了更多數(shù)據(jù)(兩個隱藏的版本號字段)
- 增加了很多檢查工作和處理完后的善后工作晋柱。
- 只能在
repeatable-read
和read-committed
隔離級別下工作。 -
read-uncommitted
隔離級別下MVCC
每次都獲取到最新的事務(wù)版本號诵叁。 -
serializable
隔離級別時雁竞,讀操作鎖定了返回的每一行。