天天看點

Spring事務的隔離級别

在spring中定義了5中不同的事務隔離級别:

1. isolation_default(一般情況下使用這種配置既可) ;

這是一個platfromtransactionmanager預設的隔離級别,使用資料庫預設的事務隔離級别。

2. isolation_read_uncommitted 4 p" l. i' f; k1 {) a. d( e5 ?: v

這是事務最低的隔離級别,它充許别外一個事務可以看到這個事務未送出的資料。這種隔離級别會産生髒讀,不可重複讀和幻像讀。

大部分資料庫預設的事物隔離級别都不會出現這種狀況) 1 n$ g7 x" u# u6 s/ u' z/ i

3. isolation_read_committed

保證一個事務修改的資料送出後才能被另外一個事務讀取。另外一個事務不能讀取該事務未送出的資料。這種事務隔離級别可以避免髒讀出現,但是可能會出現不可重複讀和幻像讀。 : u8 m# n8 g1 k( e: n

什麼是髒讀?(修改且未送出引起)

例如:

張三的工資為5000,事務a中把他的工資改為8000,但事務a尚未送出。與此同時,事務b正在讀取張三的工資,讀取到張三的工資為8000。随後,事務a發生異常,而復原了事務。張三的工資又復原為5000。最後,事務b讀取到的張三工資為8000的資料即為髒資料,事務b做了一次髒讀。' t, b j d! h# i) s$ i

(大部分資料庫預設的事物隔離級别都不會出現這種狀況) ; n$ ~" j7 a& y* ?/ g8 i

4. isolation_repeatable_read

這種事務隔離級别可以防止髒讀,不可重複讀。但是可能出現幻像讀。 3 [* {- f2 s. w+ |

什麼是不可重複讀?(修改引起) 6 h2 e% j, s7 f9 n+ m0 u4 ]" ?% e. a

例如: / ^7 y# t6 |& z' b

在事務a中,讀取到張三的工資為5000,操作沒有完成,事務還沒送出。 5 k: n6 c" [$ p: j4 l/ i" b

與此同時,事務b把張三的工資改為8000,并送出了事務。随後,在事務a中,再次讀取張三的工資,此時工資變為8000。在一個事務中前後兩次讀取的結果并不緻,導緻了不可重複讀。

(大部分資料庫預設的事物隔離級别都不會出現這種狀況) . h+ u! y9 {) }1 r8 ~% b, l; t

5. isolation_serializable

這是花費最高代價但是最可靠的事務隔離級别。事務被處理為順序執行。除了防止髒讀,不可重複讀外,還避免了幻讀。 % c0 @8 e& g" x1 x/ p3 f; h1 q

什麼是幻讀?(添加新記錄引起) 9 d! d% j. |9 w9 n+ ~

例如:

a目前工資為5000的員工有10人,事務a讀取所有工資為5000的人數為10人。此時,事務b插入一條工資也為5000的記錄。這是,事務a再次讀取工資為5000的員工,記錄為11人。此時産生了幻讀。

大部分資料庫預設的事物隔離級别都會出現這種狀況,此種事物隔離級别将帶來表級鎖)

_! o3 w6 m/ l

說明 :oracle資料庫預設的事物隔離級别已經保證了避免髒讀和不可重複讀。但可能會幻讀,避免幻讀需要加表級鎖,oracle預設行級鎖。在基于spring的事物配置中一定要慎重使用isolation_serializable的事物隔離級别。這種配置會使用表級鎖,對性能影響巨大。一般沒有特殊需要的話,配置為使用資料庫預設的事物隔離級别便可。