交易傳播

本節說明 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