探索mysql數(shù)據(jù)庫Innodb下的鎖機(jī)制

mysql默認(rèn)配置 ?innodb存儲引擎

CREATE TABLE `t_test` (

? `id` int(11) NOT NULL AUTO_INCREMENT,

? `version` int(11) DEFAULT NULL,

? PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=70 DEFAULT CHARSET=utf8;

啟動兩個session ?S1 和 ?S2;

insert:

實(shí)驗(yàn)1:delete from t_test;

? ? ? ? ? ? ?ALTER TABLE `t_test`?AUTO_INCREMENT = 1;

S1: ? ?begin;

? ? ? ? ? ? insert into t_test set version = 1;??--> 執(zhí)行成功

? ? ? ? ? ? select * from t_test; ?-->?查出被插入的數(shù)據(jù) ?id 1


S2 : ? select * from t_test; ? ? ?-->執(zhí)行成功?無數(shù)據(jù)

? ? ? ? ? ??insert into t_test set version = 1; ?--> 執(zhí)行成功

? ? ? ? ? ??select * from t_test; ? ? ?--> 查出 id = 2 的數(shù)據(jù) ?說明S1中插入的數(shù)據(jù)沒有讀取到,事務(wù)的隔離性正確。

S1 : ? ??select * from t_test; ? ? ?-->查出 id = 1 的數(shù)據(jù),說明S2中插入的數(shù)據(jù)沒有讀取到,事務(wù)的隔離性正確。

? ? ? ? ? ? commit;

? ? ? ? ? ??select * from t_test; ? ? ?-->查出 id = 1,2 的數(shù)據(jù),說明S2中插入的數(shù)據(jù)讀取到,事務(wù)的隔離性正確。

S2: ? ? ?select * from t_test; ? ? ?-->查出 id = 1,2 的數(shù)據(jù),說明S1中插入的數(shù)據(jù)讀取到,事務(wù)的隔離性正確。

實(shí)驗(yàn)2:?

delete from t_test;

ALTER TABLE `t_test`?AUTO_INCREMENT = 1;

S1: ? ?begin;

? ? ? ? ? ? insert into t_test set version = 1;??--> 執(zhí)行成功

? ? ? ? ? ? select * from t_test; ?-->?查出被插入的數(shù)據(jù) ?id 1


S2 : ? select * from t_test; ? ? ?-->執(zhí)行成功?無數(shù)據(jù)

? ? ? ? ? ? begin;

? ? ? ? ? ??insert into t_test set version = 1; ?--> 執(zhí)行成功

? ? ? ? ? ??select * from t_test; ? ? ?--> 查出 id = 2 的數(shù)據(jù) ?說明S1中插入的數(shù)據(jù)沒有讀取到,事務(wù)的隔離性正確。

S1 : ? ??select * from t_test; ? ? ?-->查出 id = 1 的數(shù)據(jù),說明S2中插入的數(shù)據(jù)沒有讀取到,事務(wù)的隔離性正確。

? ? ? ? ? ? commit;

? ? ? ? ? ??select * from t_test; ? ? ?-->查出 id = 1 的數(shù)據(jù),說明S2中插入的數(shù)據(jù)沒讀取到,事務(wù)的隔離性正確。

S2: ? ? ?select * from t_test; ? ? ?-->查出 id = 2 的數(shù)據(jù),說明S1中插入的數(shù)據(jù)沒讀取到,事務(wù)的隔離性正確。

? ? ? ? ? ? rollback; ?

?? ?? ?? ???select * from t_test; ? ? ?-->查出 id = 1的數(shù)據(jù),說明S1中插入的數(shù)據(jù)讀取到,事務(wù)的隔離性正確。

S1: ? ? ?select * from t_test; ? ? ?-->查出 id = 1的數(shù)據(jù),說明S1中插入的數(shù)據(jù)讀取到,事務(wù)的隔離性正確。

總結(jié):sql的插入操作沒有鎖表和鎖記錄相關(guān)的操作。

update:實(shí)驗(yàn)步驟比較麻煩,不想詳細(xì)記錄了。這里總結(jié)一下實(shí)驗(yàn)結(jié)果。

1.在默認(rèn)配置下,sql_safe_update=1,所以update條件中必須帶有主鍵id,不論條件中是否還有其他的字段,都是行級鎖。

2.在S1中啟動事務(wù),執(zhí)行update操作,S2中update同一條記錄會等待S1執(zhí)行完畢之后才能繼續(xù),S2中在這之后的SQL都處于等待中。

3,.set sql_safe_update = 0,允許不根據(jù)主鍵id來update數(shù)據(jù),此時mysql執(zhí)行表級鎖

4.由于update存在行級鎖,在啟動事務(wù)時要注意死鎖問題。

最后:mysql autocommit = 1; 即自動提交。如果啟動事務(wù),自動提交機(jī)制會被自動屏蔽。

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

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

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