數據庫隔離級別
說這個問題之前我們先說說三個概念。
髒讀
當一個事務正在訪問數據,並且對數據進行了修改,但這個修改了的數據還沒提交到數據庫中,然後另一個事務也訪問了這個數據,那麼我們就稱這個事務讀到的數據是髒數據。這個錯誤過程就叫髒讀。
不可重複讀
在同一個事務內,多次讀同一個數據。在這個事務還沒結束時,另一個事務也訪問這條數據並做了修改最後提交了修改數據。那麼第一個事務可能在某次讀的數據和之前的數據不同,這個問題就叫不可重複讀。
幻讀
當一個事務查詢了某個表的所有數據,這時一個事務向這張表插入一條記錄,當前一個事務再次讀取數據時,發現多了一條記錄,就像出現了幻覺一樣。
可能很多人會不清楚不可重複讀和幻讀的區別。我個人的理解是,不可重複讀重在更新某一條記錄,即避免它只需要行級鎖就行。而幻讀則重在插入刪除,避免它需要鎖住整張表。這純屬個人理解,如若有誤,請指出。
四種隔離級別
讀未提交
所有事務都可以看到其它未提交事務的執行結果。這一級別很少用在項目中,會出現上面三種錯誤情況。
讀已提交
這是大多數數據庫系統的默認隔離級別(但不是MySQL默認的,MySQL是Repeatable Read)。一個事務只能看見已經提交事務所做的改變。但它只能避免髒讀。
可重複讀
這是MySQL的默認事務隔離級別。一旦事務在讀取某條數據時,就會禁止別的事務修改它。它避免了不可重複讀這一問題,但依舊會出些幻讀。
可串行化
事務串行執行,有先後順序,肯定不會出問題啦,就是效率較低。
Spring中的事務隔離
ISOLATION_DEFAULT
默認使用數據庫當前的隔離級別。
ISOLATION_READ_UNCOMMITTED
讀未提交。
ISOLATION_READ_COMMITTED
讀已提交
ISOLATION_REPEATABLE_READ
可重複讀
ISOLATION_SERIALIZABLE
可串行化
Spring事務傳播
事務的特性
事務是程序中一系列嚴密的操作,所有操作執行必須成功完成,否則在每個操作所做的更改將會被撤銷,這也是事務的原子性(要麼成功,要麼失敗)。
傳播行爲
下面是Spring配置事務傳播和事務隔離的一個小例子: