事務隔離級別和事務傳播機制都是對事務行為的規範,但二者描述的側重點卻不同。本文這裡所說的事務隔離級別和事務傳播機制指的是 Spring 框架中的機制。
1、事務隔離級別
事務隔離級別是對事務 4 大特性中隔離性的具體體現,使用事務隔離級別可以控制並行事務在同時執行時的某種行為。
比如,有兩個事務同時操作同一張表,此時有一個事務修改了這張表的資料,但尚未提交事務,那麼在另一個事務中,要不要(或者說能不能)看到其他事務尚未提交的資料呢?
這個問題的答案就要看事務的隔離級別了,不同的事務隔離級別,對應的行為模式也是不一樣的(有些隔離級別可以看到其他事務尚未提交的資料,有些事務隔離級別看不到其他事務尚未提交的資料),這就是事務隔離級別的作用。
Sping 中的事務隔離級別有 5 種,它們分別是:
- DEFAULT:Spring 中預設的事務隔離級別,以連線的資料庫的事務隔離級別為準;
- READ_UNCOMMITTED:讀未提交,也叫未提交讀,該隔離級別的事務可以看到其他事務中未提交的資料。該隔離級別因為可以讀取到其他事務中未提交的資料,而未提交的資料可能會發生回滾,因此我們把該級別讀取到的資料稱之為髒資料,把這個問題稱之為髒讀;
- READ_COMMITTED:讀已提交,也叫提交讀,該隔離級別的事務能讀取到已經提交事務的資料,因此它不會有髒讀問題。但由於在事務的執行中可以讀取到其他事務提交的結果,所以在不同時間的相同 SQL 查詢中,可能會得到不同的結果,這種現象叫做不可重複讀;
- REPEATABLE_READ:可重複讀,它能確保同一事務多次查詢的結果一致。但也會有新的問題,比如此級別的事務正在執行時,另一個事務成功的插入了某條資料,但因為它每次查詢的結果都是一樣的,所以會導致查詢不到這條資料,自己重複插入時又失敗(因為唯一約束的原因)。明明在事務中查詢不到這條資訊,但自己就是插入不進去,這就叫幻讀 (Phantom Read);
- SERIALIZABLE:序列化,最高的事務隔離級別,它會強制事務排序,使之不會發生衝突,從而解決了髒讀、不可重複讀和幻讀問題,但因為執行效率低,所以真正使用的場景並不多。
所以,相比於 MySQL 的事務隔離級別,Spring 中多了一種 DEFAULT 的事務隔離級別。
事務隔離級別與問題的對應關係如下:
- 髒讀:一個事務讀取到了另一個事務修改的資料之後,後一個事務又進行了回滾操作,從而導致第一個事務讀取的資料是錯誤的。
- 不可重複讀:一個事務兩次查詢得到的結果不同,因為在兩次查詢中間,有另一個事務把資料修改了。
- 幻讀:一個事務兩次查詢中得到的結果集不同,因為在兩次查詢中另一個事務有新增了一部分資料。
Spring 中,事務隔離級別可以通過 @Transactional(isolation = Isolation.DEFAULT) 來設定。
2、事務傳播機制
Spring 事務傳播機制是指,包含多個事務的方法在相互呼叫時,事務是如何在這些方法間傳播的。
Spring 事務傳播機制可使用 @Transactional(propagation=Propagation.REQUIRED) 來設定,Spring 事務傳播機制的級別包含以下 7 種:
- Propagation.REQUIRED:預設的事務傳播級別,它表示如果當前存在事務,則加入該事務;如果當前沒有事務,則建立一個新的事務。
- Propagation.SUPPORTS:如果當前存在事務,則加入該事務;如果當前沒有事務,則以非事務的方式繼續執行。
- Propagation.MANDATORY:(mandatory:強制性)如果當前存在事務,則加入該事務;如果當前沒有事務,則丟擲異常。
- Propagation.REQUIRES_NEW:表示建立一個新的事務,如果當前存在事務,則把當前事務掛起。也就是說不管外部方法是否開啟事務,Propagation.REQUIRES_NEW 修飾的內部方法會新開啟自己的事務,且開啟的事務相互獨立,互不干擾。
- Propagation.NOT_SUPPORTED:以非事務方式執行,如果當前存在事務,則把當前事務掛起。
- Propagation.NEVER:以非事務方式執行,如果當前存在事務,則丟擲異常。
- Propagation.NESTED:如果當前存在事務,則建立一個事務作為當前事務的巢狀事務來執行;如果當前沒有事務,則該取值等價於 PROPAGATION_REQUIRED。
以上 7 種傳播機制,可分為以下 3 類:
總結
從上述的介紹中可以看出,事務隔離級別描述的是多個事務同時執行時的某種行為,它們的呼叫流程如下:
而事務傳播機制是描述,多個包含了事務的方法在相互呼叫時事務的傳播行為,它們的呼叫流程如下:
所以事務隔離級別描述的是縱向事務並行呼叫時的行為模式,而事務傳播機制描述的是橫向事務傳遞時的行為模式。
是非審之於己,譭譽聽之於人,得失安之於數。
公眾號:Java面試真題解析
面試合集:https://gitee.com/mydb/interview