事務傳播

本節描述了 Spring 中事務傳播的一些語義。請注意,本節並非事務傳播的恰當介紹。相反,它詳細闡述了 Spring 中事務傳播的一些語義。

在 Spring 管理的事務中,請注意物理事務和邏輯事務之間的區別,以及傳播設定如何應用於此區別。

理解 PROPAGATION_REQUIRED

tx prop required

PROPAGATION_REQUIRED 強制執行一個物理事務,如果尚無事務,則在當前作用域內本地執行;如果存在一個為更大作用域定義的“外部”事務,則參與該事務。這在同一執行緒內的常見呼叫棧安排中是一個不錯的預設值(例如,一個服務門面委託給多個儲存庫方法,其中所有底層資源都必須參與服務級別的事務)。

預設情況下,參與事務會加入外部作用域的特性,默默地忽略本地隔離級別、超時值或只讀標誌(如果有)。如果希望在參與具有不同隔離級別的現有事務時拒絕隔離級別宣告,請考慮將事務管理器上的 validateExistingTransactions 標誌切換為 true。這種非寬鬆模式還會拒絕只讀不匹配(即,嘗試參與只讀外部作用域的內部讀寫事務)。

當傳播設定為 PROPAGATION_REQUIRED 時,對於應用了該設定的每個方法,都會建立一個邏輯事務作用域。每個這樣的邏輯事務作用域可以單獨確定回滾狀態,外部事務作用域在邏輯上獨立於內部事務作用域。在標準 PROPAGATION_REQUIRED 行為的情況下,所有這些作用域都對映到同一個物理事務。因此,在內部事務作用域中設定的回滾標記確實會影響外部事務實際提交的機會。

然而,在內部事務作用域設定回滾標記的情況下,外部事務尚未自行決定回滾,因此回滾(由內部事務作用域默默觸發)是意料之外的。此時會丟擲相應的 UnexpectedRollbackException。這是預期的行為,這樣事務的呼叫者永遠不會被誤導地認為已執行了提交,而實際上並未執行。因此,如果一個內部事務(外部呼叫者不瞭解)默默地將事務標記為回滾,外部呼叫者仍然會呼叫提交。外部呼叫者需要收到 UnexpectedRollbackException 以明確指示已執行回滾。

理解 PROPAGATION_REQUIRES_NEW

tx prop requires new

PROPAGATION_REQUIRED 不同,PROPAGATION_REQUIRES_NEW 始終為每個受影響的事務作用域使用一個獨立的物理事務,從不參與外部作用域的現有事務。在這種安排中,底層資源事務是不同的,因此可以獨立提交或回滾,外部事務不受內部事務回滾狀態的影響,內部事務的鎖在其完成後立即釋放。這種獨立的內部事務也可以宣告自己的隔離級別、超時和只讀設定,而不繼承外部事務的特性。

附加到外部事務的資源將保持繫結在那裡,而內部事務獲取自己的資源,例如新的資料庫連線。這可能導致連線池耗盡,並可能導致死鎖,如果多個執行緒具有活動的外部事務並等待為其內部事務獲取新連線,而連線池無法再分配任何此類內部連線。除非您的連線池大小適當,至少超過併發執行緒數 1,否則請勿使用 PROPAGATION_REQUIRES_NEW

理解 PROPAGATION_NESTED

PROPAGATION_NESTED 使用一個帶有多個儲存點的物理事務,它可以回滾到這些儲存點。這種部分回滾允許內部事務作用域觸發其作用域的回滾,而外部事務能夠繼續物理事務,儘管某些操作已被回滾。此設定通常對映到 JDBC 儲存點,因此它僅適用於 JDBC 資源事務。請參閱 Spring 的 DataSourceTransactionManager

© . This site is unofficial and not affiliated with VMware.