MySQL 數(shù)據(jù)庫 InnoDB 自增鎖

總的來說,InnoDB 共有七種類型的鎖:
(1) 共享/排它鎖(Shared and Exclusive Locks)
(2) 意向鎖(Intention Locks)
(3) 記錄鎖(Record Locks)
(4) 間隙鎖(Gap Locks)
(5) 臨鍵鎖(Next-key Locks)
(6) 插入意向鎖(Insert Intention Locks)
(7) 自增鎖(Auto-inc Locks)

下面將結(jié)合案例,剖析 InnoDB 的自增鎖

案例

MySQL,InnoDB,默認的隔離級別(RR),假設有數(shù)據(jù)表:t(id AUTO_INCREMENT, name);
數(shù)據(jù)表中有數(shù)據(jù):

  • shenjian
  • zhangsan
  • lisi

事務A先執(zhí)行,還未提交:
insert into t(name) values(xxx);

事務B后執(zhí)行:
insert into t(name) values(ooo);

問:事務B會不會被阻塞?

分析

InnoDB在RR隔離級別下,能解決幻讀問題,上面這個案例中:
(1) 事務A先執(zhí)行insert,會得到一條(4, xxx)的記錄,由于是自增列,故不用顯示指定id為4,InnoDB會自動增長,注意此時事務并未提交;
(2) 事務B后執(zhí)行insert,假設不會被阻塞,那會得到一條(5, ooo)的記錄;

此時,并未有什么不妥,但如果

(3) 事務A繼續(xù)insert:
insert into t(name) values(xxoo);
會得到一條(6, xxoo)的記錄。
(4) 事務A再select:
select * from t where id>3;
得到的結(jié)果是:
4, xxx
6, xxoo

那么,就不可能查詢到5的記錄,再RR的隔離級別下,不可能讀取到還未提交事務生成的數(shù)據(jù)。這對于事務A來說,就很奇怪了,對于AUTO_INCREMENT的列,連續(xù)插入了兩條記錄,一條是4,接下來一條變成了6。

自增鎖

自增鎖是一種特殊的表級別鎖(table-level lock),專門針對事務插入AUTO_INCREMENT類型的列。最簡單的情況,如果一個事務正在往表中插入記錄,所有其他事務的插入必須等待,以便第一個事務插入的行,是連續(xù)的主鍵值。

與此同時,InnoDB 提供了 innodb_autoinc_lock_mode 配置,可以調(diào)節(jié)與改變該鎖的模式與行為。

上面的案例,假設不是自增列,又會是什么樣的情形呢?

t(id unique PK, name);
數(shù)據(jù)表中有數(shù)據(jù):
10, shenjian
20, zhangsan
30, lisi

事務A先執(zhí)行,在10與20兩條記錄中插入了一行,還未提交:
insert into t values(11, xxx);

事務B后執(zhí)行,也在10與20兩條記錄中插入了一行:
insert into t values(12, ooo);

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容