今天請了一天假去卓望公司面試,被問到數據庫隔離機制的問題,真的沒準備,平時的工做用到的也很少,數據庫默認機制是啥也沒怎麼關心,回來看了點資料,打開mysql測試了一下,終於清楚了!總結一下可能被問到的問題:mysql
一、數據庫有幾種隔離級別:面試
答:四種,由低到高依次爲sql
1)Read uncommitted(未受權讀取、讀未提交)、---各類好處:髒讀、虛讀(不可重複)、幻讀數據庫
2) Read committed(讀提交)、 --- :虛讀,幻讀(發現了其它事務提交的記錄)測試
3)Repeatable read(可重複讀取)、 --- :無虛讀幻讀(不能發現其它事務已提交更新或插入的數據)spa
4) Serializable(序列化)。事務
髒讀、虛(不可重複)讀、幻讀、這幾種問題容易把問題搞混亂,髒讀是指讀取了其餘事務沒有提交的數據,另外兩個是 沒有讀取到其餘事務已經提交的變化。開發
其實徹底能夠拋開這些中國人取的SB名詞,直接從本意上理解: it
我理解以下:數據庫有四種隔離級別:第一種 和 第四種 幾乎只存在於實驗室中吧,現實業務中根本不太可能用到,若是有用到的請告知我:很是感謝! 那就剩下兩種隔離級別table
2) Read commited 仍是過去式,顧名思義,讀到了已經提交的 。 說白了就是 ,事務一在執行過程當中,事務二迅速開始並提交,事務一在結束前能夠查詢到變化。
Oracle等大部分數據庫,默認使用這種隔離級別 。(update\delete\insert等只要事務提交就能查到)
3)Repeatable read 同理,事務中的查詢結果是可復現的,那就是事務結束前不能覺察到其它事務提交的變化。
Mysql 默認採用這種隔離級別。
到這裏清楚了!!
真正在開發中,數據庫定了,隔離機制也就肯定了
====================Mysql演示=============================================
-- 第1步 新建窗口,開啓事務, START TRANSACTION; SELECT *,NOW() from t1 ; -- for UPDATE; SELECT sleep(10) ; --保證執行時間足以讓其它事務執行完 SELECT t1.*,NOW() from t1 ; COMMIT;
-- 第二步,在前一段sql未結束事物前 在新的窗口執行第二個事務 START TRANSACTION; INSERT INTO t1 (name) VALUES ('b'); -- 測試幻讀 SELECT t1.*,NOW() from t1 ; COMMIT;
-- 上圖中順序:左圖執行-》右圖執行-》右圖查詢結束-》左圖查詢結束,數據庫中多了一條數據
-- 但左圖中沒有查詢到
-- 第二步,在前一段sql未結束事物前 在新的窗口執行第二個事務 START TRANSACTION; -- 測試虛讀 update t1 set t1.`name` = concat(t1.`name`,NOW()) WHERE t1.id = 1 ; SELECT t1.*,NOW() from t1 ; COMMIT;
-- 上圖中順序:左圖執行-》右圖執行-》右圖查詢結束-》左圖查詢結束,數據庫中更新了一條數據
-- 左圖中沒有查詢到,證實了mysql 默認使用可重複讀 也就是虛讀
Oracle默認的事務隔離級別是read commited,在此級別下,經過多版本的控制解決了幻讀和幻讀。
Mysql 顯然沒有,但能夠經過在數據庫中設置樂觀鎖字段或使用悲觀鎖來控制數據一致性