我有一個方法調用鏈,其中A調用B調用C調用D.A和D具有@Transactional註釋。但B和C沒有。這種情況下交易界限的範圍是什麼。是B和C部分的交易嗎?Spring事務邊界擴展
回答
默認情況下,A,B,C & D在同一事務中工作。事務的默認傳播級別是TX_REQUIRED,意思是如果一個新事務不存在(A開始一個,B,C,D參與),則開始一個新事務。
D可以通過將傳播級別設置爲TX_REQUIRES_NEW(如果您的環境支持它)來啓動新事務。在這種情況下,當D完成時,恢復暫停的事務。提交D不會影響事務A的結果。回滾A不會回滾D(已提交),因爲它們是單獨的事務。
此外,很多開發人員忘記只有公有方法可能被標記爲@Transactional,因爲Spring使用代理來管理事務(私有/受保護的方法在「this」上被調用 - 因此代理沒有機會去做它的魔法)。如果使用字節碼注入而不是代理,這並不是必需的。
如果你想了解更多關於交易設計模式,我強烈建議下面的電子書(免費! - 需要註冊):http://www.infoq.com/minibooks/JTDS。這是一個非常簡單的閱讀。
這取決於@Transactional
註釋的propagation參數。
默認情況下,A內發生的所有事情都是單個事務的一部分 - 包括直接或間接調用的所有方法。
其他傳播模式將允許D暫停當前事務並自行啓動,在嵌套事務中執行,或拋出異常,因爲它並不意味着在現有事務中使用。
我的意思是,當B和C沒有任何註釋時,是否應用默認的「需要」或...? – meisam 2011-05-18 14:58:43
在事務設計中有一條「簡單」的經驗規則:啓動事務的對象/方法也負責確定結果(提交/回滾)。在你的情況下,A在A完成之前調用B - > C - > D,因此它們參與A的事務。由於B&C沒有註釋,因此它們不是交易意識。 D有點不同,默認情況下它會檢查是否有活動事務並參與。否則,它會開始一個新的。 – 2011-05-18 15:06:33
@meisam:你看錯了方向。事務不知道方法,而只知道如何訪問事務感知資源,如數據庫。該註釋使A在執行事務之前啓動一個事務,之後每次訪問該線程中發生的事務感知資源(無論在哪種方法中)都是事務的一部分,直到A完成並提交或回退事務爲止。 – 2011-05-18 15:34:07
如果您從@Transactional A調用B和C,它們仍將處於事務中。
在spring文檔中查看transaction propagation。
獨立的會發生什麼:
,如果這個問題甚至出現時,你可能有嚴重的設計問題。
在95%的情況下,事務劃分應該在應用程序的入口點進行,即在內部調用所有其他代碼的服務方法中。
唯一有效的情況下,我可以想到@Transactional
方法調用另一個方法時,內部方法有傳播REQUIRES_NEW
。如果不是這樣:重構您的設計,以便您的代碼只通過一個@Transactional
註釋。
我同意100%。內部方法可能需要@Transactional的另一種情況是檢查事務處於活動狀態(TRX_MANDATORY):如果未找到任何異常,則會引發異常。我們在DAO上執行此操作,因此您無法直接調用DAO,必須通過服務層(REQUIRES_NEW | REQUIRED)。 – 2011-05-18 15:09:29
@Patrick我同意TRX_MANDATORY,這是唯一的TX註釋是有道理的一個DAO – 2011-05-18 15:12:04
我不同意。如果C向隊列添加任務會怎麼樣?那個任務實際上執行D?在這種情況下,您不能在同一個事務中使用它們,並且您需要爲D使用REQUIRES_NEW,儘管這不像調用DAO方法那樣直接。 – meisam 2011-05-18 16:06:39
- 1. 擴展器邊界重疊
- 2. 擴展邊界向外DIV
- 3. UIButton的擴展邊界?
- 4. 休眠事務邊界
- 5. Akka流和事務邊界
- 6. cartopy - set_extent()擴展請求邊界
- 7. 如何擴展插件邊界QTabWidget
- 8. 稍微擴展Google Map上的邊界
- 9. Android:擴展小部件和畫布邊界 - 擴展Button
- 10. Spring @Transactional邊界
- 11. 如何擴展div來補償去除邊界div的邊距?
- 12. 阻止邊界擴展爲邊距/填充
- 13. Spring Bean擴展
- 14. Spring - 擴展StartupInfoLogger
- 15. 如何調試CMT事務邊界?
- 16. 與ActiveRecord的分佈式事務邊界
- 17. NewRelic Java API和事務邊界
- 18. Google Maps v3 API擴展界限map.fitBounds無法擴展界限
- 19. EJB 3事務邊界:調用非事務性類
- 20. 擴展流暢的界面
- 21. 使用事件擴展角度服務
- 22. 擴展擺動JComboBox以移除不需要的邊界
- 23. 擴展的UIButton邊界最初未繪製
- 24. 如何使用JavaScript將選擇擴展到單詞邊界?
- 25. Python的列表擴展與隨機元素保持邊界/原
- 26. 如何計算擴展器的邊界框?
- 27. 爲什麼這個邊界對象不能被擴展?
- 28. 圖片擴展了我的容器邊界
- 29. UIViewController容器視圖內容擴展容器邊界
- 30. 如何擴展一個類的邊界而不是其他類
a)A,B,C,D在同一班級嗎? b)您是否使用JDK代理(默認),CGLib(proxy-target-class = true)或AspectJ(mode = aspectj) – 2011-05-18 14:54:19
否,它們處於不同的類別中。我使用默認配置的Spring。 – meisam 2011-05-18 16:02:36
re默認配置:這取決於你的類是否支持接口。他們? – 2011-05-18 17:12:06