您好,登錄后才能下訂單哦!
本篇內容介紹了“怎么理解事務隔離級別、MVCC、spring事物傳播屬性”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
數據庫有四種事務隔離級別
讀未提交(Read uncommitted)
讀已提交(Read committed)
可重復讀(Repeatable read)
串行化(Serializable)
以上事務隔離級別依次遞增,但是性能依次遞減。
mysql支持以上四種隔離級別,其默認是:可重復讀(Repeatable read)。
oracle數據庫支持READ COMMITTED 和 SERIALIZABLE兩種。
oracle和PostgreSQL默認是:讀已提交(Read committed)。
以上四種隔離分別會出現以下問題
隔離級別 | 臟讀 | 不可重復讀 | 幻讀 |
---|---|---|---|
讀未提交(Read uncommitted) | 可能 | 可能 | 可能 |
讀已提交(Read committed) | 不可能 | 可能 | 可能 |
可重復讀(Repeatable read) | 不可能 | 不可能 | 可能 |
串行化(Serializable) | 不可能 | 不可能 | 不可能 |
臟讀:
T1修改數據后未提交之前,T2可以訪問修改后的數據。
不可重復讀:
T1:讀取userid=1的salary=1000;
T2:將userid=1的salary改為2000并提交;
T1:此時再次讀取userid=1的記錄,則讀取不到salary=1000了,這既是不可重復讀。
幻讀:
T1:select id=1,resultset=null,此時準備插入一條;
T2:insert id=1 并提交;
T1:insert id=1 ,報錯。
在這種情況下,T1按照邏輯本來是預計成功的,但是卻報錯主鍵沖突,此時T1就產生了幻讀,仿佛看花眼出現幻象了一般。
串行化:
每個事務排隊執行。
串行話為什么不會出現幻讀?因為會鎖定索引。
還是上面幻讀的例子,T1查詢的時候,因為是主鍵查詢,數據庫會自動給索引加上鎖(索引加鎖,與具體數據無關),所以T2的操作會失敗,T1的插入會成功。當然如果我們在可重復讀模式下,通過select for update 是也可以達到Serializable的效果。
MVCC: Mulit Vsersion Concurrent Control 即:多版本并發控制
作用:解決不可重復讀問題(例:T1正在查詢數據,T2修改了,T1在查就查不到原來的數據了)
Mysql默認事務隔離級別是RR,MVCC可以保證在RC和RR模式下實現可重復讀:
每個表中會存在兩個隱藏的字段:crate_version、delete_version,這兩個字段都是用來記錄當前的事物ID(事物ID數據庫自增)。
insert:添加數據時會記錄create_version。 delete:刪除數據時會更新delete_version。 update:更新數據時會將動作拆分為insert+delete,即新增一條數據,并且吧舊數據delete_version更改為當前事物ID。 select:查詢數據時,在滿足條件的記錄上判斷: 1.create_version小于等于當前查詢事物的ID(并發插入不可見) 2.delete_version為空,或者大于當前版本ID(并發刪除可見)
由此看來,數據的更新操作并不會影響查詢的數據,實現了可重復讀。
PS: 由于舊數據并不會真正刪除,所以innodb會開啟后臺線程執行清理工作:將刪除版本號小于當前事物ID的版本進行清理,這個過程叫做purge。
事務傳播特性是指,當多個方法形成一個調用鏈時,事務是如何傳播的(如A方法中調用了B方法,那么事務是以哪種方式傳播給B)。
spring只提供事務管理器,其實現交給hibernate等其他框架;Spring定義了7中傳播行為(org.springframework.transaction包中的TransactionDefinition接口):
PROPAGATION_REQUIRED(spring默認):如果當前存在事務,則加入該事務;如果當前沒有事務,則創建一個新的事務。
PROPAGATION_SUPPORTS:如果當前存在事務,則加入該事務;如果當前沒有事務,則以非事務的方式繼續運行。
PROPAGATION_MANDATORY:如果當前存在事務,則加入該事務;如果當前沒有事務,則拋出異常。
PROPAGATIONREQUIRESNEW:創建一個新的事務,如果當前存在事務,則把當前事務掛起。
PROPAGATIONNOTSUPPORTED:以非事務方式運行,如果當前存在事務,則把當前事務掛起。
PROPAGATION_NEVER:以非事務方式運行,如果當前存在事務,則拋出異常。
PROPAGATIONNESTED:如果當前存在事務,則創建一個事務作為當前事務的嵌套事務來運行;如果當前沒有事務,則該取值等價于PROPAGATIONREQUIRED。
以上七中傳播特性中,前六種屬于EJB,被spring引進;后一種是spring特有的。
ISOLATION_DEFAULT:使用后端數據庫默認的隔離級別。
ISOLATION_READ_UNCOMMITTED:允許讀取尚未提交的更改。可能導致臟讀、幻影讀或不可重復讀。
ISOLATION_READ_COMMITTED:允許從已經提交的并發事務讀取。可防止臟讀,但幻影讀和不可重復讀仍可能會發生。
ISOLATION_REPEATABLE_READ:對相同字段的多次讀取的結果是一致的,除非數據被當前事務本身改變。可防止臟讀和不可重復讀,但幻讀仍可能發生。
ISOLATION_SERIALIZABLE:完全服從ACID的隔離級別,確保不發生臟讀、不可重復讀和幻影讀。
“怎么理解事務隔離級別、MVCC、spring事物傳播屬性”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。