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ī)制會被自動屏蔽。