數據庫事務的隔離級別有4個,由低到高依次爲Read uncommitted 、Read committed 、Repeatable read 、Serializable ,這四個級別能夠逐個解決髒讀 、不可重複讀 、幻讀這幾類問題。mysql
最低的隔離級別。一個事務能夠讀取另外一個事務並未提交的更新結果。sql
大部分數據庫採用的默認隔離級別。一個事務的更新操做結果只有在該事務提交以後,另外一個事務才能夠的讀取到同一筆數據更新後的結果。數據庫
mysql的默認級別。整個事務過程當中,對同一筆數據的讀取結果是相同的,無論其餘事務是否在對共享數據進行更新,也無論更新提交與否。併發
最高隔離級別。全部事務操做依次順序執行。注意這會致使併發度降低,性能最差。一般會用其餘併發級別加上相應的併發鎖機制來取代它。性能
髒讀發生在一個事務A讀取了被另外一個事務B修改,可是還未提交的數據。假如B回退,則事務A讀取的是無效的數據。這跟不可重複讀相似,可是第二個事務不須要執行提交。 spa
在基於鎖的並行控制方法中,若是在執行select時不添加讀鎖,就會發生不可重複讀問題。code
在多版本並行控制機制中,當一個遇到提交衝突的事務須要回退但卻被釋放時,會發生不可重複讀問題。blog
在上面這個例子中,事務2提交成功,它所作的修改已經可見。然而,事務1已經讀取了一個其它的值。在序列化和可重複讀的隔離級別中,數據庫管理系統會返回舊值,即在被事務2修改以前的值。在提交讀和未提交讀隔離級別下,可能會返回被更新的值,這就是「不可重複讀」。事務
有兩個策略能夠防止這個問題的發生:get
(1) 推遲事務2的執行,直至事務1提交或者回退。這種策略在使用鎖時應用。
(2) 而在多版本並行控制中,事務2能夠被先提交。而事務1,繼續執行在舊版本的數據上。當事務1終於嘗試提交時,數據庫會檢驗它的結果是否和事務一、事務2順序執行時同樣。若是是,則事務1提交成功。若是不是,事務1會被回退。
3 幻讀
幻讀發生在當兩個徹底相同的查詢執行時,第二次查詢所返回的結果集跟第一個查詢不相同。
發生的狀況:沒有範圍鎖。
不可重複讀的重點是修改: 一樣的條件, 你讀取過的數據, 再次讀取出來發現值不同了
例子:
在事務1中,Mary 讀取了本身的工資爲1000,操做並無完成
con1 = getConnection();
select salary from employee empId ="Mary";
在事務2中,這時財務人員修改了Mary的工資爲2000,並提交了事務.
con2 = getConnection(); update employee set salary = 2000; con2.commit();
在事務1中,Mary 再次讀取本身的工資時,工資變爲了2000
select salary from employee empId ="Mary";
在一個事務中先後兩次讀取的結果並不致,致使了不可重複讀。
例子:
目前工資爲1000的員工有10人。
事務1,讀取全部工資爲1000的員工。
con1 = getConnection();
Select * from employee where salary =1000;
共讀取10條記錄
這時另外一個事務向employee表插入了一條員工記錄,工資也爲1000
con2 = getConnection(); Insert into employee(empId,salary) values("Lili",1000); con2.commit();
事務1再次讀取全部工資爲1000的員工
select * from employee where salary =1000;
共讀取到了11條記錄,這就像產生了幻讀。