在分佈式系統中,事務的傳播行為(Transaction Propagation)指的是在不同的事務上下文中如何處理事務的傳播方式。它決定了一個方法在執行時是否應該在當前事務中運行,是否應該創建新的事務,或者是否應該加入到已有的事務中。事務傳播行為在多層架構的系統(例如 Spring 框架中)尤為重要。
常見的事務傳播行為類型
以下是 Spring 框架中的七種常用事務傳播行為,這些傳播行為可以應用於服務層或業務邏輯中不同方法之間的事務控制。
1. PROPAGATION_REQUIRED(默認)
- 描述:
如果當前沒有事務,創建一個新的事務。如果已經存在事務,加入到當前事務中。 -
行為:
- 如果方法內沒有事務,則會創建一個新的事務。
- 如果方法內已有事務,則會加入到當前事務。
- 使用場景:
大部分情況下使用此傳播行為,因為它允許方法在已有事務的上下文中執行,或者為沒有事務的操作創建新的事務。 - 舉例:
如果一個方法調用了另一個方法,而另一個方法也有事務,兩個方法將會共享同一個事務。
2. PROPAGATION_REQUIRES_NEW
- 描述:
總是創建一個新的事務。如果當前有事務存在,則會掛起當前事務,並啓動一個新的事務。 -
行為:
- 如果方法內已有事務,它會先掛起該事務,創建一個新的事務。
- 當前事務完成後,新的事務提交或回滾。
- 使用場景:
用於那些不希望被現有事務影響的操作,例如需要確保某些操作總是成功的,而不會因為外部事務失敗而回滾。 - 舉例:
假設有一個方法A,它調用了方法B,方法B使用PROPAGATION_REQUIRES_NEW,那麼方法B的事務會獨立於方法A的事務執行。即使方法A回滾,方法B也會提交。
3. PROPAGATION_SUPPORTS
- 描述:
如果當前有事務,方法將在當前事務中運行。如果沒有事務,方法將以非事務的方式運行。 -
行為:
- 如果已有事務,方法會加入到當前事務中。
- 如果沒有事務,方法將不會創建新的事務,也不參與任何事務。
- 使用場景:
用於那些可以選擇性地參與事務的操作,例如某些讀取操作,可以在沒有事務的情況下執行。 - 舉例:
一個方法執行讀取操作時,不需要強制事務,但如果外部調用者已經有事務,它會加入該事務。
4. PROPAGATION_NOT_SUPPORTED
- 描述:
總是以非事務的方式執行,如果當前存在事務,則會掛起當前事務。 -
行為:
- 當前方法不支持事務,若當前有事務,則掛起事務,執行時不在事務上下文中運行。
- 使用場景:
用於那些不希望在事務內執行的操作,例如某些不需要事務控制的操作。 - 舉例:
如果方法需要執行某些不希望參與事務的操作(例如某些批量操作),可以選擇PROPAGATION_NOT_SUPPORTED。
5. PROPAGATION_NEVER
- 描述:
如果當前存在事務,則拋出異常。該方法不支持事務。 -
行為:
- 如果方法內已有事務,拋出異常。
- 如果沒有事務,則方法會正常執行。
- 使用場景:
用於那些不能在事務內執行的操作,若存在事務則需要拋出異常。 - 舉例:
某些操作可能不希望在事務內進行,如涉及到外部系統的調用,或者某些特定的系統行為。
6. PROPAGATION_MANDATORY
- 描述:
必須在一個現有事務中執行,如果當前沒有事務,則拋出異常。 -
行為:
- 如果方法沒有事務,則拋出異常。
- 如果已有事務,方法將加入到現有事務中。
- 使用場景:
用於要求事務必須存在的場景,如果當前沒有事務,調用者會收到異常。 - 舉例:
如果方法必須在事務上下文中執行(例如某些金融系統操作),可以使用此傳播行為。
7. PROPAGATION_IDLE
- 描述:
此行為是一個比較特殊的選項,表示如果當前沒有事務,則不會創建新的事務;但如果當前有事務,則它會與當前事務共享。 -
行為:
- 如果沒有事務,它不會創建新的事務。
- 如果有事務,則它會加入到現有事務中。
傳播行為與事務隔離級別的關係
在分佈式系統中,事務傳播行為與事務隔離級別密切相關。隔離級別定義了一個事務能夠看見其他事務的修改的程度,而傳播行為則定義瞭如何在事務之間傳遞執行上下文。
- 傳播行為決定了如何啓動、加入或掛起事務。
- 隔離級別決定了事務之間的執行順序和它們對其他事務的可見性。
Spring 事務傳播行為總結表
| 傳播行為 | 如果當前存在事務 | 如果當前不存在事務 |
|---|---|---|
PROPAGATION_REQUIRED |
加入當前事務 | 創建一個新的事務 |
PROPAGATION_REQUIRES_NEW |
掛起當前事務,創建新事務 | 創建一個新的事務 |
PROPAGATION_SUPPORTS |
加入當前事務 | 非事務性執行 |
PROPAGATION_NOT_SUPPORTED |
掛起當前事務,非事務性執行 | 非事務性執行 |
PROPAGATION_NEVER |
拋出異常 | 非事務性執行 |
PROPAGATION_MANDATORY |
加入當前事務 | 拋出異常 |
總結
事務傳播行為是分佈式系統中至關重要的一部分,它決定了多個方法和事務之間如何交互。選擇合適的事務傳播行為能夠幫助確保系統的一致性、可靠性和性能。在實際開發中,通常會根據不同的業務需求和數據一致性要求來決定使用哪種傳播行為。例如,如果你希望某些方法總是加入現有事務中,則可以選擇 PROPAGATION_REQUIRED;如果某些操作必須獨立運行,則可以選擇 PROPAGATION_REQUIRES_NEW。