如何防止數據髒讀?幻讀?

2、解決辦法:

一、概念說明:   java

  更新丟失:最後的更新覆蓋了其餘事務以前的更新,而事務之間並不知道,發生更新丟失。更新丟失,能夠徹底避免,應用對訪問的數據加鎖便可。數據庫

  髒讀:(針對未提交的數據)一個事務在更新一條記錄,未提交前,第二個事務讀到了第一個事務更新後的記錄,那麼第二個事務就讀到了髒數據,會產生對第一個未提交json

數據的依賴。一旦第一個事務回滾,那麼第二個事務讀到的數據,將是錯誤的髒數據。併發

  不可重複讀:(讀取數據自己的對比)一個事務在讀取某些數據後的一段時間後,再次讀取這個數據,發現其讀取出來的數據內容已經發生了改變,就是不可重複讀。spa

  幻讀:(讀取結果集條數的對比)一個事務按相同的查詢條件查詢以前檢索過的數據,確發現檢索出來的結果集條數變多或者減小(由其餘事務插入、刪除的),相似產生幻覺。code

 

二、不可重複讀和幻讀的區別:blog

不可重複讀事務

重點是修改:一樣的條件下,你讀取過的數據,再次讀取發現值不同了。it

例子:(只是爲了說明區別,沒有事務隔離級別約束)class

事務1:Jack讀取本身的工資爲1000,事務並無結束:

select salary from employee empId ="Jack"; 

事務2:財務人員修改了Jack的工資爲2000,並提交事務(事務1不知道):

update employee set salary = 2000;

commit;

在事務1中,再次讀取Jack的工資時,工資變爲2000

select salary from employee empId ="Jack";

 

在一個事務中先後兩次讀取的結果值並不一致,致使了不可重讀讀

 

幻讀

重點在於新增或者刪除(數據條數的變化):一樣條件下,第一次和第二次讀出來的記錄條數不同。

例子:

目前工資爲1000的員工有10人。

事務1:讀取全部工資爲1000的員工,事務進行中

select count(*) from employee where salary = 1000;

共讀取到10條記錄。

事務2:同時插入一條新的員工記錄,工資也爲1000

insert into employee(empId, salary) values('Tom', 1000);

commit;

事務1:再次讀取全部工資爲1000的員工

select count(*) from employee where salary = 1000;

共讀取到了11條記錄,這樣就像產生了幻讀。

3、事務隔離級別:

  併發處理帶來的問題中,更新丟失能夠徹底避免,由應用對數據加鎖便可。髒讀、不可重讀度、幻讀,其實都是數據庫的一致性問題,必須由必定的事務隔離機制來解決。

其中一種方法是:不用加鎖,經過必定的機制生成一個數據請求時間點的一致性快照,並用這個快照來提供一個界別的一致性讀取。從用戶的角度看,好像是數據庫提偶拱了

統一數據的多個版本。這種技術叫作:數據庫多版本併發控制,MVCC 多版本數據庫

  事務隔離的本質是使事務在必定程度上串行化執行,顯然和併發機制是矛盾的。數據庫的事務隔離越嚴格,併發負做用越小,代價越高(影響併發訪問了唄)。

  爲了解決隔離和並大的矛盾,IOS SQL92規定了4個隔離級別。(隔離==串行

相關文章
相關標籤/搜索