資料庫隔離級別學習示例

2021-10-06 20:57:51 字數 3637 閱讀 2315

資料庫隔離級別有四種,每種隔離級別網上的解釋已經很多了,這裡就不多說了,我們可以看一下spring中對四種隔離級別的定義,其中default是預設隔離級別,使用資料庫的預設隔離級別。這篇文章主要是想通過一些例子來直觀感受一下各種隔離級別。

本文示例主要使用到springboot,mybatis-plus和lombok。

使用的工具:sqlyog, idea, screentogif(錄製螢幕**)

我們在service層編寫如下**,adduser方法用來新增使用者,getuser方法用來獲取使用者,其中adduser方法讓執行緒sleep 10秒(原諒我手速不行,多sleep一會),用來模擬事務長時間未提交。

@transactional

(isolation = isolation.read_uncommitted)

public

void

adduser

(user user)

catch

(interruptedexception e)

}@transactional

(isolation = isolation.read_uncommitted)

public list

getuser()

controller層通過兩個介面分別呼叫adduser和getuser

("adduser"

)public string adduser()

("getuser"

)public list

getuser()

第一種情況,我們先不加@transactional看看效果,也就是把上面service類中的@transactional註解去掉。

可以看到,adduser方法還沒返回時,資料庫就已經有資料了,getuser也能查詢到。這也很好理解,因為沒有開啟事物,adduser方法執行完就會立馬提交,不會等後面的sleep執行完再提交。

這種情況是最低的隔離級別,讀未提交,也就是乙個事務還沒有結束,另乙個事務可以讀取到事務沒提交的資料。

從下圖可以直觀地看到,adduser事務還沒結束,資料庫是查不到資料的,但是我們的getuser方法卻獲取到了這條資料!也就是讀到了另乙個事務未提交的資料。

("第二次嘗試讀取資料");

system.out.

println

(list)

;return list;

}從下圖可以明顯看出結果,在讀已提交隔離級別下,getuser在8秒內的同乙個事務中讀取兩次,讀取到的結果不一樣,這種情況稱之為不可重複讀。

還是和情況3一樣的例子,我們把隔離級別設定為可重複讀再試驗一下(repeatable_read)。

在可重複讀的隔離級別下,可以看出,即使另乙個事務已經提交了資料,並且資料庫中可以查詢到,當前事務在沒結束前,兩次的查詢結果是一樣的,從而實現了在重複讀取資料時不會出現讀取到不一致資料的情況。

不可重複讀的隔離級別下會出現的問題是幻讀,也就是說資料明明沒有讀到,但是卻可以更新資料,並且更新資料後又可以讀到這條資料了。為了試驗這種情況,我們把getuser方法再修改一下。

@transactional

(isolation = isolation.repeatable_read)

public list

getuser()

catch

(interruptedexception e)

list =

this

.lambdaquery()

.eq(user:

:getname,

"zzj").

list()

; system.out.

println

("第二次嘗試讀取資料,仍然讀取不到");

system.out.

println

(list)

;

system.out.

println

("嘗試把name為zzj的資料的age改為20");

this

.lambdaupdate()

.eq(user:

:getname,

"zzj").

set(user:

:getage,20)

.update()

;

list =

this

.lambdaquery()

.eq(user:

:getname,

"zzj").

list()

; system.out.

println

("第三次嘗試讀取資料,讀到了剛才更新的資料");

這種情況就很簡單了,在這種隔離級別下,所有事務序列執行,只有等乙個事務結果了另乙個事務才會開始執行。把getuser修改為如下,看一下試驗。

資料庫隔離級別

read uncommited 讀未提交 最低級別,可讀取未提交事物的資料,這會導致髒讀,比如 某時刻會話a修改了乙個資料,但還未提交,此時會話b,讀取了該資料,這是,會話a回滾了事物,這就導致資料出現了不一致狀態,這就是髒讀 read commited 提交讀 避免了髒讀,但會導致不可重複讀,例如...

資料庫隔離級別

資料庫事務的隔離級別有4個,由低到高依次為read uncommitted read committed repeatable read serializable,這四個級別可以逐個解決髒讀 不可重複讀 幻讀這幾類問題。可能出現 不會出現 髒讀 不可重複讀 幻讀read uncommitted re...

資料庫隔離級別

資料庫事務的隔離級別有4個,由低到高依次為read uncommitted read committed repeatable read serializable,這四個級別可以逐個解決髒讀 不可重複讀 幻讀這幾類問題。可能出現 不會出現 髒讀不可重複讀 幻讀read uncommitted rea...