不可重复 幻读
幻讀和不可重復讀的區(qū)別
2014年09月15日 20:51:27
閱讀數(shù):26195
MySQl
MySql默認的隔離級別為Repeatable Read,因此只會出現(xiàn)幻讀的情況。
?
幻讀
事務(wù)在插入已經(jīng)檢查過不存在的記錄時,驚奇的發(fā)現(xiàn)這些數(shù)據(jù)已經(jīng)存在了,之前的檢測獲取到的數(shù)據(jù)如同鬼影一般。
例子:
在事務(wù)1中,查詢User表id為1的是用戶否存在,如果不存在則插入一條id為1的數(shù)據(jù)。
?
select * from User where id = 1;在事務(wù)1查詢結(jié)束后,事務(wù)2往User表中插入了一條id為1的數(shù)據(jù)。
?
?
insert into `User`(`id`, `name`) values (1, 'Joonwhee');此時,由于事務(wù)1查詢到id為1的用戶不存在,因此插入1條id為1的數(shù)據(jù)。
?
?
insert into ` User`(`id`, `name`) values (1, 'Chillax');但是由于事務(wù)2已經(jīng)插入了1條id為1的數(shù)據(jù),因此此時會報主鍵沖突,對于事務(wù)1 的業(yè)務(wù)來說是執(zhí)行失敗的,這里事務(wù)1 就是發(fā)生了幻讀,因為事務(wù)1讀取的數(shù)據(jù)狀態(tài)并不能支持他的下一步的業(yè)務(wù),見鬼了一樣。這里要靈活的理解讀取的意思,第一次select是讀取,第二次的insert其實也屬于隱式的讀取,只不過是在mysql的機制中讀取的,插入數(shù)據(jù)也是要先讀取一下有沒有主鍵沖突才能決定是否執(zhí)行插入。
?
Oracle
Oracle默認的隔離級別為Read?Committed,因此可能出現(xiàn)不可重復度和幻讀。
?
不可重復讀
同樣的條件,你讀取過的數(shù)據(jù),再次讀取出來發(fā)現(xiàn)值不一樣了。
例子:
在事務(wù)1中,JoonWhee讀取了自己的工資為1000,但是此時事務(wù)1的操作還并沒有完成 ,后面還有1次相同的讀取操作。
?
con1 = getConnection();
select salary from employee where employeeName ="JoonWhee";
?
在事務(wù)2中,這時財務(wù)人員修改了JoonWhee的工資為2000,并提交了事務(wù)。
?
con2 = getConnection();
update employee set salary = 2000 where employeeName = "JoonWhee";
con2.commit();
?
在事務(wù)1中,JoonWhee再次讀取自己的工資時,工資變?yōu)榱?000 。
?
//con1
select salary from employee where employeeName ="JoonWhee";
?
在一個事務(wù)中前后兩次讀取的結(jié)果并不致,導致了不可重復讀。
?
幻讀
同樣的條件,第1次和第2次讀出來的記錄數(shù)不一樣。
例子:
目前工資為1000的員工有10人。?
事務(wù)1,讀取所有工資為1000的員工,共讀取10條記錄 。
?
con1 = getConnection();
Select * from employee where salary =1000;
?
這時另一個事務(wù)向employee表插入了一條員工記錄,工資也為1000?
?
con2 = getConnection();
Insert into employee(employeeName,salary) values("Lili",1000);
con2.commit();
?
事務(wù)1再次讀取所有工資為1000的員工,共讀取到了11條記錄,這就產(chǎn)生了幻讀。?
?
//con1
select * from employee where salary =1000;
https://blog.csdn.net/v123411739/article/details/39298127
總結(jié)
- 上一篇: Myeclipse 创建web项目的一些
- 下一篇: 网站怎么做404 301(网站怎么做40