版權聲明:本文為博主原創文章,未經博主允許不得轉載。微信公眾號:JoonWhee,歡迎關注。 https://blog.csdn.net/v123411739/article/details/39298127
MySQl
幻讀
事務在插入已經檢查過不存在的記錄時,驚奇的發現這些數據已經存在了,之前的檢測獲取到的數據如同鬼影一般。
例子:
在事務1中,查詢User表id為1的是用戶否存在,如果不存在則插入一條id為1的數據。
- select * from User where id = 1;
- insert into `User`(`id`, `name`) values (1, 'Joonwhee');
- insert into ` User`(`id`, `name`) values (1, 'Chillax');
Oracle
不可重復讀
同樣的條件,你讀取過的數據,再次讀取出來發現值不一樣了。
例子:
在事務1中,JoonWhee讀取了自己的工資為1000,但是此時事務1的操作還並沒有完成 ,后面還有1次相同的讀取操作。
- con1 = getConnection();
- select salary from employee where employeeName ="JoonWhee";
在事務2中,這時財務人員修改了JoonWhee的工資為2000,並提交了事務。
- con2 = getConnection();
- update employee set salary = 2000 where employeeName = "JoonWhee";
- con2.commit();
在事務1中,JoonWhee再次讀取自己的工資時,工資變為了2000 。
- //con1
- select salary from employee where employeeName ="JoonWhee";
在一個事務中前后兩次讀取的結果並不致,導致了不可重復讀。
幻讀
同樣的條件,第1次和第2次讀出來的記錄數不一樣。
例子:
目前工資為1000的員工有10人。
事務1,讀取所有工資為1000的員工,共讀取10條記錄 。
- con1 = getConnection();
- Select * from employee where salary =1000;
這時另一個事務向employee表插入了一條員工記錄,工資也為1000
- con2 = getConnection();
- Insert into employee(employeeName,salary) values("Lili",1000);
- con2.commit();
事務1再次讀取所有工資為1000的員工,共讀取到了11條記錄,這就產生了幻讀。
- //con1
- select * from employee where salary =1000;
鏈接:https://www.zhihu.com/question/47007926/answer/253406510
來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
臟讀:(同時操作都沒提交的讀取)
臟讀又稱無效數據讀出。一個事務讀取另外一個事務還沒有提交的數據叫臟讀。
例如:事務T1修改了一行數據,但是還沒有提交,這時候事務T2讀取了被事務T1修改后的數據,之后事務T1因為某種原因Rollback了,那么事務T2讀取的數據就是臟的。
解決辦法:把數據庫的事務隔離級別調整到READ_COMMITTED
不可重復讀:(同時操作,事務一分別讀取事務二操作時和提交后的數據,讀取的記錄內容不一致)
不可重復讀是指在同一個事務內,兩個相同的查詢返回了不同的結果。
例如:事務T1讀取某一數據,事務T2讀取並修改了該數據,T1為了對讀取值進行檢驗而再次讀取該數據,便得到了不同的結果。 解決辦法:把數據庫的事務隔離級別調整到REPEATABLE_READ
幻讀:(和可重復讀類似,但是事務二的數據操作僅僅是插入和刪除,不是修改數據,讀取的記錄數量前后不一致)
例如:系統管理員A將數據庫中所有學生的成績從具體分數改為ABCDE等級,但是系統管理員B就在這個時候插入(注意時插入或者刪除,不是修改))了一條具體分數的記錄,當系統管理員A改結束后發現還有一條記錄沒有改過來,就好像發生了幻覺一樣。這就叫幻讀。
解決辦法:把數據庫的事務隔離級別調整到SERIALIZABLE_READ