版本 6.0.0
參考文檔的這一部分涉及數(shù)據(jù)訪問和 數(shù)據(jù)訪問層與業(yè)務(wù)或服務(wù)層之間的交互。
Spring的全面事務(wù)管理支持已經(jīng)詳細介紹, 然后全面涵蓋各種數(shù)據(jù)訪問框架和技術(shù) Spring 框架與之集成。
1. 交易管理
全面的事務(wù)支持是使用Spring的最令人信服的理由之一。 框架。Spring 框架為事務(wù)提供了一致的抽象 具有以下優(yōu)勢的管理:
- 跨不同事務(wù) API(如 Java)的一致編程模型 事務(wù) API (JTA)、JDBC、Hibernate 和 Java Persistence API (JPA)。
- 支持聲明式事務(wù)管理。
- 用于編程事務(wù)管理的更簡單的 API 而不是復(fù)雜的事務(wù) API,例如 JTA。
- 與 Spring 的數(shù)據(jù)訪問抽象完美集成。
以下部分描述了 Spring 框架的事務(wù)特性和 技術(shù):
- Spring 框架事務(wù)支持的優(yōu)勢 模型描述了為什么你會使用Spring Framework的事務(wù)抽象 而不是 EJB 容器管理事務(wù) (CMT) 或選擇在本地驅(qū)動 通過專有 API 進行交易,例如 Hibernate。
- 了解 Spring 框架事務(wù)抽象概述了核心類,并描述了如何配置和獲取來自各種來源的實例。
DataSource
- 將資源與事務(wù)同步說明 應(yīng)用程序代碼如何確保創(chuàng)建、重用和清理資源 適當(dāng)?shù)亍?/li>
- 聲明性事務(wù)管理描述了對 聲明式事務(wù)管理。
- 程序化事務(wù)管理涵蓋對以下各項的支持 編程(即顯式編碼)事務(wù)管理。
- 事務(wù)綁定事件描述如何使用應(yīng)用程序 事務(wù)中的事件。
本章還包括對最佳實踐、應(yīng)用服務(wù)器集成、 以及常見問題的解決方案。
1.1. Spring 框架事務(wù)支持模型的優(yōu)勢
傳統(tǒng)上,EE 應(yīng)用程序開發(fā)人員有兩種事務(wù)管理選擇: 全球或本地交易,兩者都有深刻的局限性。全球 和本地事務(wù)管理將在接下來的兩個部分中進行回顧,然后是 討論 Spring 框架的事務(wù)管理支持如何解決 全局和本地事務(wù)模型的局限性。
1.1.1. 全球交易
全局事務(wù)允許您使用多個事務(wù)資源,通常 關(guān)系數(shù)據(jù)庫和消息隊列。應(yīng)用程序服務(wù)器管理全局 通過 JTA 進行交易,這是一個繁瑣的 API(部分原因是 異常模型)。此外,JTA通常需要來自 JNDI,這意味著您還需要使用 JNDI 才能使用 JTA。用途 的全局事務(wù)限制了應(yīng)用程序代碼的任何潛在重用,因為 JTA 是 通常僅在應(yīng)用程序服務(wù)器環(huán)境中可用。??UserTransaction?
?
以前,使用全局事務(wù)的首選方法是通過 EJB CMT (容器管理事務(wù))。CMT 是聲明式交易的一種形式 管理(有別于程序化事務(wù)管理)。EJB CMT 消除了與事務(wù)相關(guān)的 JNDI 查找的需要,盡管使用了 EJB 本身需要使用 JNDI。它消除了大部分但不是全部的寫入需求 用于控制事務(wù)的 Java 代碼。顯著的缺點是CMT與JTA綁定。 和應(yīng)用程序服務(wù)器環(huán)境。此外,它僅在選擇時才可用 在 EJB 中實現(xiàn)業(yè)務(wù)邏輯(或至少在事務(wù)性 EJB 外觀后面)。這 一般來說,EJB的負面因素是如此之大,以至于這不是一個有吸引力的主張, 特別是面對聲明式事務(wù)管理的令人信服的替代方案。
1.1.2. 本地交易
本地事務(wù)是特定于資源的,例如與 JDBC 關(guān)聯(lián)的事務(wù) 連接。本地事務(wù)可能更易于使用,但有一個明顯的缺點: 它們不能跨多個事務(wù)資源工作。例如,管理 使用 JDBC 連接的事務(wù)不能在全局 JTA 事務(wù)中運行。因為 應(yīng)用程序服務(wù)器不參與事務(wù)管理,它不能幫助確保 跨多個資源的正確性。(值得注意的是,大多數(shù)應(yīng)用程序使用 單個事務(wù)資源。另一個缺點是本地交易是侵入性的 到編程模型。
1.1.3. Spring 框架的一致編程模型
Spring 解決了全球和本地交易的缺點。它讓 應(yīng)用程序開發(fā)人員在任何環(huán)境中都使用一致的編程模型。 您編寫一次代碼,它就可以從不同的事務(wù)管理中受益 不同環(huán)境中的策略。Spring 框架提供了聲明式和 程序化事務(wù)管理。大多數(shù)用戶更喜歡聲明式事務(wù) 管理,我們在大多數(shù)情況下建議這樣做。
通過編程事務(wù)管理,開發(fā)人員可以使用 Spring 框架 事務(wù)抽象,可以在任何底層事務(wù)基礎(chǔ)結(jié)構(gòu)上運行。 使用首選的聲明性模型,開發(fā)人員通常編寫很少或沒有代碼 與事務(wù)管理相關(guān),因此不依賴于 Spring 框架 事務(wù) API 或任何其他事務(wù) API。
您是否需要應(yīng)用程序服務(wù)器進行事務(wù)管理?
Spring 框架的事務(wù)管理支持改變了傳統(tǒng)的規(guī)則: 當(dāng)企業(yè) Java 應(yīng)用程序需要應(yīng)用程序服務(wù)器時。
特別是,您不需要純粹用于聲明性事務(wù)的應(yīng)用程序服務(wù)器 通過 EJB。事實上,即使您的應(yīng)用服務(wù)器具有強大的 JTA 功能, 你可能會決定 Spring 框架的聲明式事務(wù)提供更多的功能和 比 EJB CMT 更高效的編程模型。
通常,僅當(dāng)應(yīng)用程序需要時才需要應(yīng)用程序服務(wù)器的 JTA 功能。 處理跨多個資源的事務(wù),這不是許多資源的要求 應(yīng)用。許多高端應(yīng)用程序使用單個高度可擴展的數(shù)據(jù)庫(例如 甲骨文 RAC) 取而代之。獨立的事務(wù)管理器(如Atomikos Transactions和JOTM) 是其他選項。當(dāng)然,您可能需要其他應(yīng)用程序服務(wù)器功能,例如 Java Message Service (JMS) 和 Jakarta EE Connector Architecture (JCA)。
Spring 框架使您可以選擇何時將應(yīng)用程序擴展到完全 加載的應(yīng)用程序服務(wù)器。使用 EJB 的唯一替代方法的日子已經(jīng)一去不復(fù)返了 CMT或JTA是用本地事務(wù)(例如JDBC連接上的事務(wù))編寫代碼 如果您需要該代碼在容器管理的全局范圍內(nèi)運行,則需要大量返工 交易。使用 Spring 框架,只有 配置文件需要更改(而不是您的代碼)。
1.2. 理解 Spring 框架事務(wù)抽象
Spring 事務(wù)抽象的關(guān)鍵是事務(wù)策略的概念。一個 事務(wù)策略由 A 定義,具體接口為命令式 事務(wù)管理和反應(yīng)式接口 事務(wù)管理。以下清單顯示了 API 的定義:??TransactionManager?
???org.springframework.transaction.PlatformTransactionManager?
???org.springframework.transaction.ReactiveTransactionManager?
???PlatformTransactionManager?
?
這主要是一個服務(wù)提供程序接口 (SPI),盡管您可以從應(yīng)用程序代碼以編程方式使用它。因為是一個接口,所以它可以很容易地被嘲笑或存根為 必要。它不依賴于查找策略,例如JNDI.實現(xiàn)的定義與任何其他對象(或bean)相同。 在 Spring Framework IoC 容器中。僅此好處就使 Spring 框架 事務(wù)是一個有價值的抽象,即使您使用 JTA 也是如此。你可以測試 事務(wù)代碼比直接使用 JTA 容易得多。??PlatformTransactionManager?
???PlatformTransactionManager?
?
再次,為了與春天的哲學(xué)保持一致,可以拋出 通過任何接口的方法都是未選中的(那 是,它擴展了類)。事務(wù)基礎(chǔ)結(jié)構(gòu) 失敗幾乎總是致命的。在極少數(shù)情況下,應(yīng)用程序代碼實際上可以 從事務(wù)失敗中恢復(fù),應(yīng)用程序開發(fā)人員仍然可以選擇捕獲 和處理。突出的一點是開發(fā)人員不是被迫這樣做的。??TransactionException?
???PlatformTransactionManager?
???java.lang.RuntimeException?
???TransactionException?
?
該方法返回一個對象,具體取決于參數(shù)。返回的可能表示 新事務(wù)或可以表示現(xiàn)有事務(wù)(如果是匹配事務(wù)) 存在于當(dāng)前調(diào)用堆棧中。后一種情況的含義是,與 Jakarta EE 事務(wù)上下文,與 執(zhí)行。??getTransaction(..)?
???TransactionStatus?
???TransactionDefinition?
???TransactionStatus?
???TransactionStatus?
?
從Spring Framework 5.2開始,Spring還提供了事務(wù)管理抽象 使用反應(yīng)式類型或 Kotlin 協(xié)程的反應(yīng)式應(yīng)用程序。以下 列表顯示由以下人員定義的交易策略:??org.springframework.transaction.ReactiveTransactionManager?
?
反應(yīng)式事務(wù)管理器主要是一個服務(wù)提供者接口 (SPI), 盡管您可以從您的 應(yīng)用程序代碼。因為是一個界面,所以很容易 必要時嘲笑或存根。??ReactiveTransactionManager?
?
該接口指定:??TransactionDefinition?
?
- 傳播:通常,事務(wù)范圍內(nèi)的所有代碼都在 那筆交易。但是,您可以指定行為,如果 當(dāng)事務(wù)上下文已存在時,將運行事務(wù)方法。為 例如,代碼可以繼續(xù)在現(xiàn)有事務(wù)中運行(常見情況),或者 可以暫?,F(xiàn)有事務(wù)并創(chuàng)建新事務(wù)。春天 提供了 EJB CMT 中熟悉的所有事務(wù)傳播選項。要閱讀 關(guān)于 Spring 中事務(wù)傳播的語義,請參閱事務(wù)傳播。
- 隔離:此事務(wù)與其他事務(wù)的工作隔離的程度 交易。例如,此事務(wù)是否可以看到來自其他事務(wù)的未提交寫入 交易?
- 超時:此事務(wù)在超時并自動回滾之前運行的時間 通過底層事務(wù)基礎(chǔ)結(jié)構(gòu)。
- 只讀狀態(tài):當(dāng)代碼讀取但 不修改數(shù)據(jù)。在某些方面,只讀事務(wù)可能是一個有用的優(yōu)化 情況,例如當(dāng)您使用休眠時。
這些設(shè)置反映了標(biāo)準(zhǔn)的事務(wù)概念。如有必要,請參閱資源 討論事務(wù)隔離級別和其他核心事務(wù)概念。 理解這些概念對于使用 Spring 框架或任何 事務(wù)管理解決方案。
該接口為事務(wù)代碼提供了一種簡單的方法 控制事務(wù)執(zhí)行和查詢事務(wù)狀態(tài)。這些概念應(yīng)該是 熟悉,因為它們對所有事務(wù) API 都是通用的。以下清單顯示了界面:??TransactionStatus?
???TransactionStatus?
?
無論您在 春天,定義正確的實現(xiàn)是絕對必要的。 通常通過依賴關(guān)系注入來定義此實現(xiàn)。??TransactionManager?
?
??TransactionManager?
?實現(xiàn)通常需要了解以下環(huán)境: 他們工作:JDBC,JTA,Hibernate等。以下示例演示如何 定義一個本地實現(xiàn)(在本例中,使用 plain JDBC.)??PlatformTransactionManager?
?
您可以通過創(chuàng)建類似于以下內(nèi)容的 Bean 來定義 JDBC:??DataSource?
?
然后,相關(guān) bean 定義具有對定義的引用。它應(yīng)類似于以下示例:??PlatformTransactionManager?
???DataSource?
?
如果您在 Jakarta EE 容器中使用 JTA,則使用容器,獲得 通過JNDI,與Spring’s一起。以下示例 顯示了 JTA 和 JNDI 查找版本的外觀:??DataSource?
???JtaTransactionManager?
?
不需要知道(或任何其他 特定資源),因為它使用容器的全局事務(wù)管理 基礎(chǔ)設(shè)施。??JtaTransactionManager?
???DataSource?
?
在所有 Spring 事務(wù)設(shè)置中,應(yīng)用程序代碼不需要更改。您可以更改 如何僅通過更改配置來管理事務(wù),即使該更改意味著 從本地事務(wù)轉(zhuǎn)移到全局事務(wù),反之亦然。
1.2.1. 休眠事務(wù)設(shè)置
您還可以輕松使用 Hibernate 本地事務(wù),如以下示例所示。 在這種情況下,您需要定義一個休眠,您的 應(yīng)用程序代碼可用于獲取休眠實例。??LocalSessionFactoryBean?
???Session?
?
Thebean 定義類似于前面顯示的本地 JDBC 示例 因此,以下示例中未顯示。??DataSource?
?
在這種情況下,Thebean屬于該類型。在 與需要引用的方式相同,需要引用。以下 示例聲明和豆子:??txManager?
???HibernateTransactionManager?
???DataSourceTransactionManager?
???DataSource?
???HibernateTransactionManager?
???SessionFactory?
???sessionFactory?
???txManager?
?
如果使用 Hibernate 和 Jakarta EE 容器管理的 JTA 事務(wù),則應(yīng)使用 與前面的 JDBC JTA 示例中相同,如下所示 示例顯示。此外,建議通過其使Hibernate知道JTA 事務(wù)協(xié)調(diào)器,可能還有其連接釋放模式配置:??JtaTransactionManager?
?
或者,您也可以將 ther傳遞給您的以強制執(zhí)行相同的默認值:??JtaTransactionManager?
???LocalSessionFactoryBean?
?
1.3. 將資源與事務(wù)同步
如何創(chuàng)建不同的事務(wù)管理器以及如何將它們鏈接到相關(guān)資源 需要同步到事務(wù)(例如,到 JDBC,到休眠, 等等)現(xiàn)在應(yīng)該很清楚了。本節(jié)介紹應(yīng)用程序如何編碼 (直接或間接地,通過使用持久性 API,如 JDBC、Hibernate 或 JPA) 確保正確創(chuàng)建、重用和清理這些資源。該部分 還討論了如何(可選)通過 相關(guān)。??DataSourceTransactionManager?
???DataSource?
???HibernateTransactionManager?
???SessionFactory?
???TransactionManager?
?
1.3.1. 高級同步方法
首選方法是使用 Spring 最高級別的基于模板的持久性 集成 API 或?qū)⒈緳C ORM API 與事務(wù)感知工廠 Bean 一起使用,或 用于管理本機資源工廠的代理。這些事務(wù)感知解決方案 內(nèi)部處理資源創(chuàng)建和重用、清理、可選事務(wù) 資源同步和異常映射。因此,用戶數(shù)據(jù)訪問代碼確實 不必處理這些任務(wù),但可以完全專注于非樣板 持久性邏輯。通常,您使用本機ORM API或采用模板方法 對于 JDBC 訪問,請使用。這些解決方案將在后續(xù)中詳細介紹 部分。??JdbcTemplate?
?
1.3.2. 低級同步方法
諸如(對于JDBC),(對于JPA),(對于Hibernate)等類存在于較低的級別。當(dāng)您想要 直接處理本機持久性 API 的資源類型的應(yīng)用程序代碼, 您可以使用這些類來確保獲得正確的 Spring 框架管理的實例, 事務(wù)(可選)同步,流程中發(fā)生的異常是 正確映射到一致的 API。??DataSourceUtils?
???EntityManagerFactoryUtils?
???SessionFactoryUtils?
?
例如,在 JDBC 的情況下,而不是傳統(tǒng)的 JDBC 調(diào)用方法 方法上,你可以改用 Spring 的類,如下所示:??getConnection()?
???DataSource?
???org.springframework.jdbc.datasource.DataSourceUtils?
?
如果現(xiàn)有事務(wù)已具有同步(鏈接)的連接,則 返回實例。否則,方法調(diào)用將觸發(fā)創(chuàng)建新的 連接,(可選)同步到任何現(xiàn)有事務(wù)并已建立 可用于同一事務(wù)中的后續(xù)重用。如前所述,anyis 包裝在一個 Spring 框架中,一個 的 Spring 框架的未選中類型層次結(jié)構(gòu)。這種方法 為您提供比從和輕松獲得的更多信息 確??鐢?shù)據(jù)庫甚至跨不同持久性技術(shù)的可移植性。??SQLException?
???CannotGetJdbcConnectionException?
???DataAccessException?
???SQLException?
?
這種方法也可以在沒有 Spring 事務(wù)管理的情況下工作(事務(wù) 同步是可選的),因此無論您是否將 Spring 用于 事務(wù)管理。
當(dāng)然,一旦你使用了 Spring 的 JDBC 支持、JPA 支持或 Hibernate 支持, 您通常不希望使用其他幫助程序類, 因為通過 Spring 抽象工作比直接工作更快樂 使用相關(guān) API。例如,如果使用 Springorpackage 來簡化 JDBC 的使用,則會發(fā)生正確的連接檢索 在幕后,您無需編寫任何特殊代碼。??DataSourceUtils?
???JdbcTemplate?
???jdbc.object?
?
1.3.3. ??TransactionAwareDataSourceProxy?
?
在最低的層次上存在類。這是一個 目標(biāo)的代理,它包裝目標(biāo)以增加對 彈簧管理的交易。在這方面,它類似于雅加達EE服務(wù)器提供的事務(wù)性JNDI。??TransactionAwareDataSourceProxy?
???DataSource?
???DataSource?
???DataSource?
?
你幾乎永遠不需要或想要使用這個類,除非存在 必須調(diào)用代碼并傳遞標(biāo)準(zhǔn)的 JDBC接口實現(xiàn)。在 在這種情況下,此代碼可能可用,但正在參與 Spring 托管 交易??梢允褂酶呒墑e編寫新代碼 前面提到的抽象。??DataSource?
?
1.4. 聲明式事務(wù)管理
Spring 框架的聲明式事務(wù)管理可以通過 Spring 實現(xiàn) 面向方面的編程 (AOP)。但是,隨著事務(wù)方面的代碼出現(xiàn) 與 Spring 框架發(fā)行版一起使用,可以以樣板方式使用 AOP 通常不必理解概念即可有效使用此代碼。
Spring 框架的聲明式事務(wù)管理類似于 EJB CMT,因為它 您可以指定事務(wù)行為(或缺少事務(wù)行為)到單個方法級別。 您可以在事務(wù)上下文中進行 acall,如果 必要。兩種類型的事務(wù)管理之間的區(qū)別是:??setRollbackOnly()?
?
- 與與JTA綁定的EJB CMT不同,Spring Framework的聲明式事務(wù)。 管理適用于任何環(huán)境。它可以與JTA事務(wù)或本地 使用 JDBC、JPA 或休眠通過調(diào)整配置進行事務(wù) 文件。
- 您可以將 Spring 框架聲明式事務(wù)管理應(yīng)用于任何類, 不僅僅是像EJB這樣的特殊類。
- Spring 框架提供了聲明式回滾規(guī)則,這是一個沒有 EJB 的特性 等效。提供對回滾規(guī)則的編程和聲明性支持。
- Spring 框架允許您使用 AOP 自定義事務(wù)行為。 例如,您可以在事務(wù)回滾的情況下插入自定義行為。你 還可以添加任意建議以及事務(wù)性建議。使用 EJB CMT,您可以 不能影響容器的事務(wù)管理,除非 。
setRollbackOnly()
- Spring 框架不支持跨事務(wù)上下文的傳播 遠程調(diào)用,就像高端應(yīng)用程序服務(wù)器一樣。如果您需要此功能,我們 建議您使用 EJB。但是,在使用此類功能之前,請仔細考慮, 因為,通常情況下,人們不希望事務(wù)跨越遠程調(diào)用。
回滾規(guī)則的概念很重要。它們允許您指定哪些例外 (和可拋擲對象)應(yīng)導(dǎo)致自動回滾。您可以在 配置,而不是在 Java 代碼中。所以,雖然你仍然可以打電話 對象回滾當(dāng)前事務(wù),最常見的是 可以指定必須始終導(dǎo)致回滾的規(guī)則。這 此選項的顯著優(yōu)點是業(yè)務(wù)對象不依賴于 事務(wù)基礎(chǔ)結(jié)構(gòu)。例如,他們通常不需要導(dǎo)入Spring。 事務(wù) API 或其他 Spring API。??setRollbackOnly()?
???TransactionStatus?
???MyApplicationException?
?
盡管 EJB 容器缺省行為會自動回滾 系統(tǒng)異常(通常是運行時異常),EJB CMT 不會回滾 在應(yīng)用程序異常(即已檢查的異常)上自動執(zhí)行事務(wù) 除此之外)。雖然 Spring 默認行為 聲明式事務(wù)管理遵循 EJB 約定(回滾僅自動進行 在未經(jīng)檢查的異常中),自定義此行為通常很有用。??java.rmi.RemoteException?
?
1.4.1. 理解 Spring 框架的聲明式事務(wù)實現(xiàn)
僅僅告訴你用注釋來注釋你的類是不夠的,添加到你的配置中, 并期望您了解這一切是如何工作的。為了提供更深入的理解,這 部分解釋了 Spring 框架聲明式事務(wù)的內(nèi)部工作原理 交易相關(guān)問題背景下的基礎(chǔ)設(shè)施。??@Transactional?
???@EnableTransactionManagement?
?
關(guān)于 Spring 框架的聲明式要掌握的最重要的概念 事務(wù)支持是通過AOP 代理啟用的,并且事務(wù) 建議由元數(shù)據(jù)(目前基于 XML 或注釋)驅(qū)動。AOP的組合 使用事務(wù)元數(shù)據(jù)生成使用 ain 的 AOP 代理 結(jié)合適當(dāng)?shù)膶崿F(xiàn)來驅(qū)動事務(wù) 圍繞方法調(diào)用。??TransactionInterceptor?
???TransactionManager?
?
Spring 框架提供事務(wù)管理 命令式和響應(yīng)式編程模型。攔截器檢測所需的風(fēng)味 通過檢查方法返回類型進行事務(wù)管理。返回反應(yīng)式的方法 諸如 Kotlin 的類型(或其中的子類型)有資格進行反應(yīng) 事務(wù)管理。所有其他返回類型,包括使用 命令式事務(wù)管理。??TransactionInterceptor?
???Publisher?
???Flow?
???void?
?
事務(wù)管理風(fēng)格會影響需要哪個事務(wù)管理器。祈使的 事務(wù)需要 A,而響應(yīng)式事務(wù)使用實現(xiàn)。??PlatformTransactionManager?
???ReactiveTransactionManager?
?
下圖顯示了在事務(wù)代理上調(diào)用方法的概念視圖:
1.4.2. 聲明式事務(wù)實現(xiàn)示例
請考慮以下接口及其伴隨的實現(xiàn)。此示例使用 andclasses 作為占位符,以便您可以專注于事務(wù) 不關(guān)注特定域模型的使用情況。就本例而言, TheClass 在每個實現(xiàn)方法的主體中拋出實例這一事實很好。該行為可讓您看到 正在創(chuàng)建事務(wù),然后回滾以響應(yīng)實例。以下清單顯示了界面:??Foo?
???Bar?
???DefaultFooService?
???UnsupportedOperationException?
???UnsupportedOperationException?
???FooService?
?
以下示例顯示了上述接口的實現(xiàn):
假設(shè)接口的前兩種方法,并且,必須在事務(wù)的上下文中以只讀方式運行 語義和其他方法,并且,必須 在具有讀寫語義的事務(wù)上下文中運行。以下 配置將在接下來的幾段中詳細說明:??FooService?
???getFoo(String)?
???getFoo(String, String)?
???insertFoo(Foo)?
???updateFoo(Foo)?
?
檢查上述配置。它假定您要創(chuàng)建一個服務(wù)對象, 底豆,事務(wù)性。要應(yīng)用的事務(wù)語義已封裝 在定義中。該定義讀作“所有方法 從 ARE 開始在只讀事務(wù)的上下文中運行,并且所有 其他方法是使用默認事務(wù)語義運行”。標(biāo)簽的屬性設(shè)置為將驅(qū)動事務(wù)的bean的名稱(在本例中為bean)。??fooService?
???<tx:advice/>?
???<tx:advice/>?
???get?
???transaction-manager?
???<tx:advice/>?
???TransactionManager?
???txManager?
?
該定義確保由 bean 定義的事務(wù)建議在程序中的適當(dāng)點運行。首先,定義一個 與接口中定義的任何操作的執(zhí)行相匹配的切入點 ().然后,您將切入點與 theby 使用 顧問。結(jié)果表明,在執(zhí)行 a 時, 定義 by 的建議運行。??<aop:config/>?
???txAdvice?
???FooService?
???fooServiceOperation?
???txAdvice?
???fooServiceOperation?
???txAdvice?
?
元素中定義的表達式是AspectJ切入點 表達。有關(guān)切入點的更多詳細信息,請參閱AOP 部分 春天的表情。??<aop:pointcut/>?
?
一個常見的要求是使整個服務(wù)層具有事務(wù)性。最好的方式 這樣做是為了更改切入點表達式以匹配 服務(wù)層。以下示例演示如何執(zhí)行此操作:
現(xiàn)在我們已經(jīng)分析了配置,您可能會問自己, “所有這些配置實際上有什么作用?”
前面顯示的配置用于圍繞對象創(chuàng)建事務(wù)代理 這是根據(jù) Thebean 定義創(chuàng)建的。代理配置為 事務(wù)性建議,以便在代理上調(diào)用適當(dāng)?shù)姆椒〞r, 事務(wù)已啟動、掛起、標(biāo)記為只讀等,具體取決于 與該方法關(guān)聯(lián)的事務(wù)配置??紤]以下程序 該測試驅(qū)動前面顯示的配置:??fooService?
?
運行上述程序的輸出應(yīng)類似于以下內(nèi)容(Log4J 為清楚起見,來自 thePose by Theclass 方法的輸出和堆棧跟蹤已被截斷):??UnsupportedOperationException?
???insertFoo(..)?
???DefaultFooService?
?
要使用反應(yīng)式事務(wù)管理,代碼必須使用反應(yīng)式類型。
下面的清單顯示了以前使用的修改版本,但是 這次代碼使用反應(yīng)式類型:??FooService?
?
以下示例顯示了上述接口的實現(xiàn):
命令式和響應(yīng)式事務(wù)管理共享相同的事務(wù)語義 邊界和事務(wù)屬性定義。命令式的主要區(qū)別 反應(yīng)式事務(wù)是后者的延遲性質(zhì)。使用事務(wù)運算符修飾返回的反應(yīng)式類型以開始和清理 事務(wù)。因此,調(diào)用事務(wù)反應(yīng)式方法會延遲實際 對激活反應(yīng)式處理的訂閱類型的事務(wù)管理 類型。??TransactionInterceptor?
?
反應(yīng)式事務(wù)管理的另一個方面與數(shù)據(jù)轉(zhuǎn)義有關(guān),即 編程模型的自然結(jié)果。
命令性事務(wù)的方法返回值從事務(wù)方法返回 成功終止方法后,使部分計算的結(jié)果不會逃逸 方法閉包。
反應(yīng)式事務(wù)方法返回一個反應(yīng)式包裝器類型,該類型表示 計算序列以及開始和完成計算的承諾。
Acan 可以在事務(wù)正在進行但不一定完成時發(fā)出數(shù)據(jù)。 因此,依賴于成功完成整個事務(wù)的方法需要 以確保調(diào)用代碼中的完成和緩沖結(jié)果。??Publisher?
?
1.4.3. 回滾聲明式事務(wù)
上一節(jié)概述了如何為 類,通常是服務(wù)層類,在應(yīng)用程序中以聲明方式提供。本節(jié) 描述如何在簡單的聲明性中控制事務(wù)的回滾 XML 配置中的時尚。有關(guān)以聲明方式控制回滾語義的詳細信息 使用注釋,請參閱@Transactional設(shè)置。??@Transactional?
?
向 Spring 框架的事務(wù)基礎(chǔ)結(jié)構(gòu)指示的推薦方法 事務(wù)的工作要回滾是拋出一個代碼 當(dāng)前正在事務(wù)上下文中執(zhí)行。Spring 框架的 事務(wù)基礎(chǔ)結(jié)構(gòu)代碼在冒泡時捕獲任何未處理的內(nèi)容 調(diào)用堆棧,并確定是否將事務(wù)標(biāo)記為回滾。??Exception?
???Exception?
?
在其默認配置中,Spring 框架的事務(wù)基礎(chǔ)結(jié)構(gòu)代碼 僅在運行時、未經(jīng)檢查的異常情況下將事務(wù)標(biāo)記為回滾。 也就是說,當(dāng)拋出的異常是 的實例或子類時。 (默認情況下,實例也會導(dǎo)致回滾)。已檢查的異常 從事務(wù)方法引發(fā)不會導(dǎo)致默認回滾 配置。??RuntimeException?
???Error?
?
您可以準(zhǔn)確配置哪些類型將事務(wù)標(biāo)記為回滾, 通過指定回滾規(guī)則包括已檢查的異常。??Exception?
?
回滾規(guī)則
回滾規(guī)則確定當(dāng)給定異常 拋出,規(guī)則基于異常類型或異常模式。
回滾規(guī)則可以通過 theandattributes 在 XML 中配置,這允許將規(guī)則定義為模式。使用@Transactional時,回滾規(guī)則可能會 通過 /和/屬性進行配置,這允許規(guī)則 分別基于異常類型或模式定義。?
?rollback-for?
???no-rollback-for?
???rollbackFor?
???noRollbackFor?
???rollbackForClassName?
???noRollbackForClassName?
?使用異常類型定義回滾規(guī)則時,該類型將用于匹配 針對拋出的異常類型及其超類型,提供類型安全和 避免使用模式時可能發(fā)生的任何意外匹配。例如,一個 值將僅匹配拋出的異常 類型及其子類。?
?jakarta.servlet.ServletException.class?
???jakarta.servlet.ServletException?
?使用例外模式定義回滾規(guī)則時,該模式可以是完全 異常類型的限定類名或完全限定類名的子字符串 (必須是 的子類),目前沒有通配符支持。為 例如,一個值 oforwill 匹配及其子類。?
?Throwable?
???"jakarta.servlet.ServletException"?
???"ServletException"?
???jakarta.servlet.ServletException?
?
以下 XML 代碼段演示如何為選中的、 應(yīng)用程序特定類型,通過屬性提供異常模式:??Exception?
???rollback-for?
?
如果您不希望在引發(fā)異常時回滾事務(wù),您還可以 指定“無回滾”規(guī)則。下面的例子告訴 Spring 框架的 事務(wù)基礎(chǔ)結(jié)構(gòu),即使在面對 未處理:??InstrumentNotFoundException?
?
當(dāng) Spring 框架的事務(wù)基礎(chǔ)結(jié)構(gòu)捕獲異常并查詢 配置的回滾規(guī)則,以確定是否將事務(wù)標(biāo)記為回滾, 最強的匹配規(guī)則獲勝。因此,在以下配置的情況下,任何 除 an 以外的異常導(dǎo)致回滾 服務(wù)員交易:??InstrumentNotFoundException?
?
還可以以編程方式指示所需的回滾。雖然簡單,但這個過程 非常具有侵入性,并且將您的代碼與 Spring 框架的事務(wù)緊密耦合 基礎(chǔ)設(shè)施。下面的示例演示如何以編程方式指示必需的 反轉(zhuǎn):
爪哇島
科特林
強烈建議您使用聲明性方法進行回滾(如果有的話) 可能。如果您絕對需要,可以使用編程回滾,但它 使用與實現(xiàn)基于 POJO 的干凈架構(gòu)背道而馳。
1.4.4. 為不同的 bean 配置不同的事務(wù)語義
考慮以下場景:您有許多服務(wù)層對象,并且您希望 對它們中的每一個應(yīng)用完全不同的事務(wù)配置。你可以這樣做 通過定義具有不同和屬性值的不同元素。??<aop:advisor/>?
???pointcut?
???advice-ref?
?
作為比較點,首先假設(shè)所有服務(wù)圖層類都是 在根包中定義。使所有 bean 都是類的實例 在該包(或子包)中定義,并且名稱以 with 結(jié)尾 默認事務(wù)配置,您可以編寫以下內(nèi)容:??x.y.service?
???Service?
?
以下示例顯示了如何使用完全不同的 Bean 配置兩個不同的 bean 事務(wù)設(shè)置:
1.4.5. <tx:建議/>設(shè)置
本節(jié)總結(jié)了可以使用以下命令指定的各種事務(wù)設(shè)置 標(biāo)簽。默認設(shè)置為:??<tx:advice/>?
???<tx:advice/>?
?
- 傳播設(shè)置為
REQUIRED.
- 隔離級別為
DEFAULT.
- 事務(wù)是讀寫的。
- 事務(wù)超時默認為基礎(chǔ)事務(wù)的默認超時 系統(tǒng)或無(如果不支持超時)。
- 任何觸發(fā)器回滾,任何選中的都不會。
RuntimeException
Exception
您可以更改這些默認設(shè)置。下表總結(jié)了標(biāo)簽的各種屬性 嵌套在標(biāo)簽中:??<tx:method/>?
???<tx:advice/>?
???<tx:attributes/>?
?
表 1.<tx:方法/>設(shè)置
屬性 |
必填? |
違約 |
描述 |
? |
是的 |
要與事務(wù)屬性關(guān)聯(lián)的方法名稱。這 通配符 (*) 字符可用于關(guān)聯(lián)同一事務(wù)屬性 具有多種方法(例如,,,,等)的設(shè)置 四)。? |
|
? |
不 |
? |
事務(wù)傳播行為。 |
? |
不 |
? |
事務(wù)隔離級別。僅適用于傳播設(shè)置 ofor。? |
? |
不 |
-1 |
事務(wù)超時(秒)。僅適用于傳播器。? |
? |
不 |
假 |
讀寫事務(wù)與只讀事務(wù)。僅適用于 toor。? |
? |
不 |
以逗號分隔的觸發(fā)回滾的實例列表。例如。? |
|
? |
不 |
以逗號分隔的不觸發(fā)回滾的實例列表。例如。? |
1.4.6. 使用??@Transactional?
?
除了基于 XML 的事務(wù)配置聲明性方法之外,您還可以 使用基于注釋的方法。直接在 Java 中聲明事務(wù)語義 源代碼使聲明更接近受影響的代碼。沒有多少 過度耦合的危險,因為用于事務(wù)性的代碼是 無論如何,幾乎總是以這種方式部署。
使用注釋提供的易用性是最好的 用一個示例進行說明,該示例在下面的文本中進行了說明。 請考慮以下類定義:??@Transactional?
?
使 Bean 實例具有事務(wù)性的行。 |
如上所述在類級別使用,注釋指示所有方法的默認值 聲明類(及其子類)?;蛘?,每種方法都可以 單獨注釋。有關(guān)方法可見性和@Transactional 有關(guān) Spring 認為哪些方法具有事務(wù)性的更多詳細信息。請注意,類級別 注釋不適用于類層次結(jié)構(gòu)中的祖先類;在這種情況下, 繼承的方法需要在本地重新聲明才能參與 子類級別注釋。
當(dāng)像上面這樣的 POJO 類被定義為 Spring 上下文中的 bean 時, 您可以通過 aclass 中的 anannotation 使 Bean 實例成為事務(wù)性實例。有關(guān)完整的詳細信息,請參閱javadoc。??@EnableTransactionManagement?
???@Configuration?
?
在 XML 配置中,標(biāo)記提供了類似的便利:??<tx:annotation-driven/>?
?
與命令式相反,反應(yīng)式事務(wù)方法使用反應(yīng)式返回類型 編程安排如下表所示:
請注意,對于返回的 反應(yīng)流取消信號。請參閱下面的取消信號部分 “使用事務(wù)運算符”以獲取更多詳細信息。??Publisher?
?
方法可見性和?
?@Transactional?
?當(dāng)您使用具有 Spring 標(biāo)準(zhǔn)配置的事務(wù)代理時,您應(yīng)該應(yīng)用 僅對具有可見性的方法進行注釋。如果你這樣做 注釋,或包可見的方法 使用注釋,不會引發(fā)錯誤,但注釋方法不顯示已配置的 事務(wù)設(shè)置。如果需要注釋非公共方法,請考慮中的提示 以下段落用于基于類的代理或考慮使用 AspectJ 編譯時或 加載時編織(稍后描述)。?
?@Transactional?
???public?
???protected?
???private?
???@Transactional?
?在類中使用時,或 包可見的方法也可以通過以下方式為基于類的代理提供事務(wù)性 注冊自定義Bean,如以下示例所示。 但請注意,基于接口的代理中的事務(wù)方法必須始終在代理接口中定義。?
?@EnableTransactionManagement?
???@Configuration?
???protected?
???transactionAttributeSource?
???public?
?Spring TestContext Framework通過以下方式支持非私有測試方法 違約。請參閱測試中的事務(wù)管理 章節(jié)為例。?
?@Transactional?
?
您可以將注釋應(yīng)用于接口定義,一種方法 在接口、類定義或類上的方法上。然而, 僅僅存在注釋不足以激活 事務(wù)行為。注釋只是元數(shù)據(jù),可以 被一些感知的運行時基礎(chǔ)結(jié)構(gòu)使用,并且 可以使用元數(shù)據(jù)來配置具有事務(wù)行為的相應(yīng) Bean。 在前面的示例中,元素打開 事務(wù)行為。?@Transactional?
???@Transactional?
???@Transactional?
???@Transactional?
???<tx:annotation-driven/>?
?
請考慮使用 AspectJ 模式(請參閱下表中的屬性),如果您 期望自我調(diào)用也與事務(wù)一起包裝。在這種情況下,有 首先沒有代理。相反,目標(biāo)類是編織的(即,它的字節(jié)碼 修改)以支持任何類型的方法上的運行時行為。??mode?
???@Transactional?
?
表 2.注釋驅(qū)動的事務(wù)設(shè)置
XML 屬性 |
注釋屬性 |
違約 |
描述 |
? |
N/A (參見TransactionManagementConfigurerjavadoc) |
? |
要使用的事務(wù)管理器的名稱。僅當(dāng)事務(wù)名稱時才需要 管理器不是,如前面的示例所示。? |
? |
? |
? |
默認模式 () 使用 Spring 的 AOP 處理要代理的帶注釋的 bean 框架(遵循代理語義,如前所述,應(yīng)用于方法調(diào)用 僅通過代理進入)。替代模式 () 相反,編織了 受影響的類與 Spring 的 AspectJ 事務(wù)方面,修改目標(biāo)類 應(yīng)用于任何類型的方法調(diào)用的字節(jié)碼。AspectJ 編織要求在類路徑中以及具有加載時編織(或編譯時) 編織)啟用。(有關(guān)如何設(shè)置加載時間編織的詳細信息,請參見Spring 配置?。? |
? |
? |
? |
僅適用于模式??刂苿?chuàng)建哪種類型的事務(wù)代理 對于用注釋注釋的類。如果屬性設(shè)置為 ,則創(chuàng)建基于類的代理。 如果省略該屬性,則為標(biāo)準(zhǔn) JDK 創(chuàng)建基于接口的代理。(有關(guān)不同代理類型的詳細檢查,請參閱代理機制?。? |
? |
? |
? |
定義應(yīng)用于注釋的 bean 的事務(wù)通知的順序。(有關(guān) AOP 排序相關(guān)規(guī)則的更多信息 建議,請參閱建議排序?。 沒有指定的順序意味著 AOP 子系統(tǒng)確定建議的順序。? |
在評估事務(wù)設(shè)置時,派生位置最多優(yōu)先 對于方法。在以下示例中,類是 在類級別使用只讀事務(wù)的設(shè)置進行注釋,但對同一類中的方法進行注釋需要 優(yōu)先于在類級別定義的事務(wù)設(shè)置。??DefaultFooService?
???@Transactional?
???updateFoo(Foo)?
?
??@Transactional?
?設(shè)置
注釋是指定接口、類、 或方法必須具有事務(wù)語義(例如,“啟動全新的只讀 調(diào)用此方法時的事務(wù),暫停任何現(xiàn)有事務(wù)“)。 默認設(shè)置如下:??@Transactional?
???@Transactional?
?
- 傳播設(shè)置為
PROPAGATION_REQUIRED.
- 隔離級別為
ISOLATION_DEFAULT.
- 事務(wù)是讀寫的。
- 事務(wù)超時默認為基礎(chǔ)事務(wù)的默認超時 系統(tǒng),如果不支持超時,則為無。
- 任何觸發(fā)器回滾,以及任何選中的回滾 不。
RuntimeException
Error
Exception
您可以更改這些默認設(shè)置。下表總結(jié)了各種 注釋的屬性:??@Transactional?
?
表 3.@Transactional設(shè)置
財產(chǎn) |
類型 |
描述 |
價值 |
? |
指定要使用的事務(wù)管理器的可選限定符。 |
? |
? |
別名。? |
? |
用于向事務(wù)添加富有表現(xiàn)力的描述的標(biāo)簽數(shù)組。? |
事務(wù)管理器可以評估標(biāo)簽,以將特定于實現(xiàn)的行為與實際事務(wù)相關(guān)聯(lián)。 |
增殖 |
? |
可選的傳播設(shè)置。 |
? |
? |
可選隔離級別。僅適用于傳播值 ofor。? |
? |
? |
可選的事務(wù)超時。僅適用于傳播值 ofor。? |
? |
? |
將秒數(shù)指定為值的替代方法,例如,作為占位符。? |
? |
? |
讀寫事務(wù)與只讀事務(wù)。僅適用于值 ofor。? |
? |
對象數(shù)組,必須派生自? |
必須導(dǎo)致回滾的異常類型的可選數(shù)組。 |
? |
異常名稱模式數(shù)組。 |
必須導(dǎo)致回滾的異常名稱模式的可選數(shù)組。 |
? |
對象數(shù)組,必須派生自? |
不得導(dǎo)致回滾的異常類型的可選數(shù)組。 |
? |
異常名稱模式數(shù)組。 |
不得導(dǎo)致回滾的異常名稱模式的可選數(shù)組。 |
目前,您無法顯式控制事務(wù)的名稱,其中“名稱” 表示事務(wù)監(jiān)視器中顯示的事務(wù)名稱(如果適用) (例如,WebLogic 的事務(wù)監(jiān)視器),并在日志記錄輸出中。對于聲明性 事務(wù),事務(wù)名稱始終是完全限定的類名 ++ 事務(wù)建議類的方法名稱。例如,如果類的方法啟動了一個事務(wù),則 事務(wù)的名稱將是:。??.?
???handlePayment(..)?
???BusinessService?
???com.example.BusinessService.handlePayment?
?
多個事務(wù)管理器??@Transactional?
?
大多數(shù) Spring 應(yīng)用程序只需要一個事務(wù)管理器,但可能存在 您希望在單個事務(wù)管理器中具有多個獨立事務(wù)管理器的情況 應(yīng)用。您可以使用注釋的 theorattribute 來選擇性地指定要使用的標(biāo)識。這可以是 Bean 名稱或限定符值 的事務(wù)管理器 Bean。例如,使用限定符表示法,您可以 將以下 Java 代碼與以下事務(wù)管理器 Bean 聲明相結(jié)合 在應(yīng)用程序上下文中:??value?
???transactionManager?
???@Transactional?
???TransactionManager?
?
以下清單顯示了 Bean 聲明:
在這種情況下,各個方法在單獨的 事務(wù)管理器,由 、 和限定符區(qū)分。默認目標(biāo) Bean 名稱,, 如果未找到特定限定的 Bean,則仍使用。??TransactionalService?
???order?
???account?
???reactive-account?
???<tx:annotation-driven>?
???transactionManager?
???TransactionManager?
?
自定義撰寫批注
如果你發(fā)現(xiàn)你反復(fù)使用相同的屬性和許多不同的 方法,Spring的元標(biāo)注支持讓你 為您的特定用例定義自定義組合注釋。例如,考慮 以下注釋定義:??@Transactional?
?
前面的注釋讓我們編寫上一節(jié)中的示例,如下所示:
在前面的示例中,我們使用語法來定義事務(wù)管理器限定符 和事務(wù)標(biāo)簽,但我們也可以包括傳播行為, 回滾規(guī)則、超時和其他功能。
1.4.7. 事務(wù)傳播
本節(jié)介紹 Spring 中事務(wù)傳播的一些語義。注意 本節(jié)不是對事務(wù)傳播的正確介紹。相反,它 詳細介紹了 Spring 中有關(guān)事務(wù)傳播的一些語義。
在 Spring 管理的交易中,請注意物理和 邏輯事務(wù),以及傳播設(shè)置如何應(yīng)用于此差異。
理解??PROPAGATION_REQUIRED?
?
??PROPAGATION_REQUIRED?
?強制實施物理事務(wù),無論是本地的當(dāng)前 范圍,如果尚不存在事務(wù)或參與現(xiàn)有的“外部”事務(wù) 為更大的范圍定義。這是常見調(diào)用堆棧安排中的良好默認值 在同一線程中(例如,委托給多個存儲庫方法的服務(wù)外觀 其中所有底層資源都必須參與服務(wù)級別事務(wù))。
當(dāng)傳播設(shè)置為邏輯事務(wù)范圍時 為應(yīng)用設(shè)置的每個方法創(chuàng)建。每個這樣的邏輯 事務(wù)范圍可以單獨確定僅回滾狀態(tài),具有外部 事務(wù)范圍在邏輯上獨立于內(nèi)部事務(wù)范圍。 在標(biāo)準(zhǔn)行為的情況下,所有這些作用域都是 映射到同一物理事務(wù)。因此,在內(nèi)部設(shè)置了僅回滾標(biāo)記 事務(wù)范圍確實會影響外部事務(wù)實際提交的機會。??PROPAGATION_REQUIRED?
???PROPAGATION_REQUIRED?
?
但是,在內(nèi)部事務(wù)范圍設(shè)置僅回滾標(biāo)記的情況下, 外部事務(wù)尚未決定回滾本身,因此回滾(靜默 由內(nèi)部事務(wù)范圍觸發(fā))是意外的。一個對應(yīng)的是拋出的那個點。這是預(yù)期行為,因此 事務(wù)的調(diào)用方永遠不會被誤導(dǎo),認為提交是 當(dāng)它真的不是時執(zhí)行。因此,如果一個內(nèi)部事務(wù)(其中外部調(diào)用者 不知道)靜默地將事務(wù)標(biāo)記為僅回滾,外部調(diào)用方仍然 調(diào)用提交。外部調(diào)用方需要接收 anto 清楚地指示已執(zhí)行回滾。??UnexpectedRollbackException?
???UnexpectedRollbackException?
?
理解??PROPAGATION_REQUIRES_NEW?
?
??PROPAGATION_REQUIRES_NEW?
??,相反,始終使用 每個受影響的事務(wù)范圍的獨立物理事務(wù),從不 參與外部范圍的現(xiàn)有事務(wù)。在這樣的安排下, 基礎(chǔ)資源事務(wù)是不同的,因此可以提交或回滾 獨立,外部事務(wù)不受內(nèi)部事務(wù)回滾的影響 狀態(tài),并在內(nèi)部事務(wù)完成后立即釋放其鎖。 這樣獨立的內(nèi)部事務(wù)還可以聲明自己的隔離級別、超時、 和只讀設(shè)置,并且不繼承外部事務(wù)的特征。??PROPAGATION_REQUIRED?
?
理解??PROPAGATION_NESTED?
?
??PROPAGATION_NESTED?
?使用具有多個保存點的單個物理事務(wù) 它可以回滾到。這種部分回滾允許內(nèi)部事務(wù)范圍 觸發(fā)其范圍的回滾,外部事務(wù)能夠繼續(xù) 盡管某些操作已回滾,但物理事務(wù)。此設(shè)置 通常映射到 JDBC 保存點,因此它僅適用于 JDBC 資源 交易。請參閱 Spring 的DataSourceTransactionManager。
1.4.8. 為交易操作提供建議
假設(shè)您要同時運行事務(wù)操作和一些基本的分析建議。 您如何在上下文中對此產(chǎn)生影響???<tx:annotation-driven/>?
?
調(diào)用該方法時,希望看到以下操作:??updateFoo(Foo)?
?
- 配置的分析方面將啟動。
- 事務(wù)性建議運行。
- 建議對象上的方法將運行。
- 事務(wù)提交。
- 分析方面報告整個事務(wù)方法調(diào)用的確切持續(xù)時間。
以下代碼顯示了前面討論的簡單性能分析方面:
建議的順序 通過接口進行控制。有關(guān)建議排序的完整詳細信息,請參閱建議排序。??Ordered?
?
以下配置創(chuàng)建具有分析和 按所需順序應(yīng)用于它的事務(wù)方面:??fooService?
?
您可以配置任何號碼 以類似的方式進行的其他方面。
下面的示例創(chuàng)建與前兩個示例相同的設(shè)置,但使用純 XML 聲明性方法:
上述配置的結(jié)果是具有分析和 事務(wù)方面按該順序應(yīng)用于它。如果您需要分析建議 在交易建議之后運行 交易建議 在出路時,您可以交換分析的價值 方面豆的屬性,使其高于交易建議的 訂單價值。??fooService?
???order?
?
您可以以類似的方式配置其他方面。
1.4.9. 與方面J一起使用??@Transactional?
?
你也可以在Spring之外使用Spring Framework的支持。 容器通過AspectJ方面。為此,請先為課程添加批注 (以及可選的類的方法)與注釋, 然后將您的應(yīng)用程序與文件中定義的應(yīng)用程序鏈接(編織)。您還必須使用事務(wù)配置方面 經(jīng)理。你可以使用 Spring 框架的 IoC 容器來處理 依賴注入方面。配置事務(wù)的最簡單方法 管理方面是使用元素并指定屬性 toas 中所述@Transactional。因為 我們在這里重點介紹在 Spring 容器之外運行的應(yīng)用程序,我們展示 你如何以編程方式做到這一點。??@Transactional?
???@Transactional?
???org.springframework.transaction.aspectj.AnnotationTransactionAspect?
???spring-aspects.jar?
???<tx:annotation-driven/>?
???mode?
???aspectj?
?
下面的示例演示如何創(chuàng)建事務(wù)管理器并配置使用它:??AnnotationTransactionAspect?
?
類上的注釋指定默認事務(wù)語義 用于執(zhí)行類中的任何公共方法。??@Transactional?
?
類中方法的注釋將覆蓋默認值 由類注釋(如果存在)給出的事務(wù)語義。您可以注釋任何方法, 無論能見度如何。??@Transactional?
?
要編織您的應(yīng)用程序,您必須構(gòu)建 您使用AspectJ的應(yīng)用程序(請參閱AspectJ開發(fā) 指南)或使用加載時間編織。請參閱加載時編織 Spring 框架中的AspectJ 討論使用 AspectJ 進行加載時間編織。??AnnotationTransactionAspect?
?
1.5. 程序化交易管理
Spring 框架提供了兩種編程事務(wù)管理方法,方法是:
- 理論。
TransactionTemplate
TransactionalOperator
- 直接實施。
TransactionManager
春季團隊通常推薦用于程序化 命令式流和響應(yīng)式代碼中的事務(wù)管理。 第二種方法類似于使用 JTAAPI,盡管有例外 處理不那么麻煩。??TransactionTemplate?
???TransactionalOperator?
???UserTransaction?
?
1.5.1. 使用??TransactionTemplate?
?
采用與其他 Spring 模板相同的方法,例如 這。它使用回調(diào)方法(將應(yīng)用程序代碼從 執(zhí)行樣板獲取并釋放事務(wù)資源)并導(dǎo)致 意圖驅(qū)動的代碼,因為您的代碼只關(guān)注什么 你想做。??TransactionTemplate?
???JdbcTemplate?
?
必須在事務(wù)上下文中運行并顯式使用下一個示例的應(yīng)用程序代碼。您,作為應(yīng)用程序 開發(fā)人員,可以編寫一個實現(xiàn)(通常表示為 匿名內(nèi)部類),其中包含需要在 一個事務(wù)。然后,您可以傳遞在 上公開的自定義方法的實例。以下示例演示如何執(zhí)行此操作:??TransactionTemplate?
???TransactionCallback?
???TransactionCallback?
???execute(..)?
???TransactionTemplate?
?
如果沒有返回值,可以使用 方便類 使用匿名類,如下所示:??TransactionCallbackWithoutResult?
回調(diào)中的代碼可以通過調(diào)用提供的對象的方法來回滾事務(wù),如下所示:??setRollbackOnly()?
???TransactionStatus?
?
指定事務(wù)設(shè)置
您可以指定事務(wù)設(shè)置(例如傳播模式、隔離級別、 超時等)以編程方式或在 配置。默認情況下,實例具有默認的事務(wù)設(shè)置。這 以下示例顯示了 的事務(wù)設(shè)置的編程自定義 一個特定的??TransactionTemplate?
???TransactionTemplate?
???TransactionTemplate:?
?
以下示例使用一些自定義事務(wù)定義 使用 Spring XML 配置進行設(shè)置:??TransactionTemplate?
?
然后,您可以根據(jù)需要注入任意數(shù)量的服務(wù)。??sharedTransactionTemplate?
?
最后,類的實例是線程安全的,在該實例中 不維護任何會話狀態(tài)。但是,實例可以維護 維護配置狀態(tài)。因此,雖然許多類可以共享一個實例 的,如果一個類需要使用 awith 不同的設(shè)置(例如,不同的隔離級別),您需要創(chuàng)建 兩個不同的實例。??TransactionTemplate?
???TransactionTemplate?
???TransactionTemplate?
???TransactionTemplate?
???TransactionTemplate?
?
1.5.2. 使用??TransactionalOperator?
?
遵循類似于其他反應(yīng)式的操作員設(shè)計 運營商。它使用回調(diào)方法(將應(yīng)用程序代碼從執(zhí)行 樣板獲取和發(fā)布事務(wù)資源),并生成 意圖驅(qū)動,因為你的代碼只關(guān)注你想要做的事情。??TransactionalOperator?
?
必須在事務(wù)上下文中運行且顯式使用的應(yīng)用程序代碼 下面是下一個示例:??TransactionalOperator?
?
爪哇島
科特林
??TransactionalOperator?
?可以通過兩種方式使用:
- 使用項目反應(yīng)器類型 (
mono.as(transactionalOperator::transactional)
) - 其他所有情況的回調(diào)樣式 (
transactionalOperator.execute(TransactionCallback<T>)
)
回調(diào)中的代碼可以通過調(diào)用提供的對象的方法來回滾事務(wù),如下所示:??setRollbackOnly()?
???ReactiveTransaction?
?
爪哇島
科特林
取消信號
在反應(yīng)流中,acan 可以取消它的 ss并停止它。Project Reactor 以及其他庫中的操作員(例如,,, 和其他人)可以發(fā)布取消。沒有辦法 了解取消的原因,無論是由于錯誤還是僅僅是由于缺乏 興趣進一步消費。從版本 5.3 開始,取消信號會導(dǎo)致回滾。 因此,重要的是要考慮交易下游使用的運算符。特別是在aor或其他多值的情況下, 必須使用完整輸出才能完成事務(wù)。??Subscriber?
???Subscription?
???Publisher?
???next()?
???take(long)?
???timeout(Duration)?
???Publisher?
???Flux?
???Publisher?
?
指定事務(wù)設(shè)置
您可以指定事務(wù)設(shè)置(例如傳播模式、隔離級別、 超時,依此類推)。默認情況下,實例具有默認事務(wù)設(shè)置。這 以下示例顯示了特定事務(wù)設(shè)置的自定義??TransactionalOperator?
???TransactionalOperator?
???TransactionalOperator:?
?
1.5.3. 使用??TransactionManager?
?
以下部分解釋命令式事務(wù)和反應(yīng)式事務(wù)的編程用法 經(jīng)理。
使用??PlatformTransactionManager?
?
對于命令式事務(wù),您可以直接使用 來管理您的 交易。為此,請通過您的實施 通過 Bean 引用用于您的 Bean。然后,通過使用 theandobjects,您可以啟動事務(wù)、回滾和提交。這 以下示例演示如何執(zhí)行此操作:??org.springframework.transaction.PlatformTransactionManager?
???PlatformTransactionManager?
???TransactionDefinition?
???TransactionStatus?
?
使用??ReactiveTransactionManager?
?
使用反應(yīng)式事務(wù)時,您可以直接使用 來管理您的 交易。為此,請通過您的實施 通過 Bean 引用用于您的 Bean。然后,通過使用 theandobjects,您可以啟動事務(wù)、回滾和提交。這 以下示例演示如何執(zhí)行此操作:??org.springframework.transaction.ReactiveTransactionManager?
???ReactiveTransactionManager?
???TransactionDefinition?
???ReactiveTransaction?
?
1.6. 在程序化和聲明式事務(wù)管理之間進行選擇
程序化事務(wù)管理通常是一個好主意,只有當(dāng)你有一個小 事務(wù)操作數(shù)。例如,如果您有一個 Web 應(yīng)用程序 僅對某些更新操作需要事務(wù),您可能不想設(shè)置 使用 Spring 或任何其他技術(shù)的交易代理。在這種情況下,使用可能是一個很好的方法。能夠設(shè)置交易名稱 顯式也是只能通過使用編程方法才能完成的事情 到事務(wù)管理。??TransactionTemplate?
?
另一方面,如果應(yīng)用程序具有大量事務(wù)操作, 聲明式事務(wù)管理通常是值得的。它保持交易 管理脫離業(yè)務(wù)邏輯,配置起來并不困難。使用 Spring Framework,而不是 EJB CMT,聲明式事務(wù)的配置成本 管理大大減少。
1.7. 交易綁定事件
從 Spring 4.2 開始,事件的偵聽器可以綁定到事務(wù)的某個階段。 典型的示例是在事務(wù)成功完成時處理事件。 這樣做可以讓事件在當(dāng)前結(jié)果時更靈活地使用 事務(wù)實際上對偵聽器很重要。
您可以使用注釋注冊常規(guī)事件偵聽器。 如果需要將其綁定到事務(wù),請使用。 執(zhí)行此操作時,默認情況下偵聽器綁定到事務(wù)的提交階段。??@EventListener?
???@TransactionalEventListener?
?
下一個示例演示了此概念。假設(shè)組件發(fā)布訂單創(chuàng)建 事件,并且我們想要定義一個偵聽器,該偵聽器應(yīng)該只處理該事件一次 已發(fā)布它的事務(wù)已成功提交。以下 示例設(shè)置這樣的事件偵聽器:
Theannotation 公開了一個屬性,讓你 自定義偵聽器應(yīng)綁定到的事務(wù)階段。 有效階段是(默認)以及聚合事務(wù)完成的階段(無論是提交還是回滾)。??@TransactionalEventListener?
???phase?
???BEFORE_COMMIT?
???AFTER_COMMIT?
???AFTER_ROLLBACK?
???AFTER_COMPLETION?
?
如果沒有事務(wù)正在運行,則根本不調(diào)用偵聽器,因為我們無法遵循 必需的語義。但是,您可以通過將批注的屬性設(shè)置為來覆蓋該行為。??fallbackExecution?
???true?
?
? |
1.8. 特定于應(yīng)用程序服務(wù)器的集成
Spring 的事務(wù)抽象通常與應(yīng)用程序服務(wù)器無關(guān)。此外 Spring’sclass(可以選擇性地執(zhí)行 JNDI 查找 JTAand對象)自動檢測位置 后一個對象,因應(yīng)用程序服務(wù)器而異。訪問 JTA 可以增強事務(wù)語義 — 特別是, 支持交易暫停。有關(guān)詳細信息,請參閱JtaTransactionManagerjavadoc。??JtaTransactionManager?
???UserTransaction?
???TransactionManager?
???TransactionManager?
?
Spring’s是運行Jakarta EE應(yīng)用程序的標(biāo)準(zhǔn)選擇 服務(wù)器,并且已知可在所有常見服務(wù)器上工作。高級功能,例如 交易暫停,也適用于許多服務(wù)器(包括GlassFish,JBoss和 杰羅尼莫),無需任何特殊配置。但是,對于完全支持 交易暫停和進一步的高級集成,Spring 包括特殊的適配器 適用于 WebLogic Server 和 WebSphere。下面將討論這些適配器 部分。??JtaTransactionManager?
?
對于標(biāo)準(zhǔn)方案,包括 WebLogic Server 和 WebSphere,請考慮使用 方便的配置元素。配置后, 此元素會自動檢測底層服務(wù)器并選擇最佳 可用于平臺的事務(wù)管理器。這意味著您不需要明確 配置特定于服務(wù)器的適配器類(如以下各節(jié)所述)。 相反,它們是自動選擇的,標(biāo)準(zhǔn)作為默認回退。??<tx:jta-transaction-manager/>?
???JtaTransactionManager?
?
1.8.1. IBM WebSphere
在 WebSphere 6.1.0.9 及更高版本上,建議使用的 Spring JTA 事務(wù)管理器是。這個特殊的適配器使用 IBM 的 API, 在 WebSphere Application Server 6.1.0.9 及更高版本中可用。使用此適配器, Spring 驅(qū)動的事務(wù)暫停(由發(fā)起者暫停和恢復(fù))由 IBM 正式支持。??WebSphereUowTransactionManager?
???UOWManager?
???PROPAGATION_REQUIRES_NEW?
?
1.8.2. Oracle WebLogic Server
在 WebLogic Server 9.0 或更高版本上,您通常會使用 the,而不是 stockclass。這 normal的特殊WebLogic特定子類支持: Spring 的事務(wù)定義在 WebLogic 管理的事務(wù)中的全部功能 環(huán)境,超越標(biāo)準(zhǔn) JTA 語義。功能包括交易名稱, 每個事務(wù)的隔離級別,并在所有情況下正確恢復(fù)事務(wù)。??WebLogicJtaTransactionManager?
???JtaTransactionManager?
???JtaTransactionManager?
?
1.9. 常見問題的解決方案
本節(jié)介紹一些常見問題的解決方案。
1.9.1. 對特定事務(wù)管理器使用錯誤的事務(wù)管理器??DataSource?
?
根據(jù)您選擇的 事務(wù)技術(shù)和要求。正確使用,Spring 框架僅 提供簡單且可移植的抽象。如果使用全局 事務(wù),您必須使用類(或特定于應(yīng)用程序服務(wù)器的子類 it) 用于您的所有事務(wù)操作。否則,事務(wù)基礎(chǔ)結(jié)構(gòu) 嘗試對容器實例等資源執(zhí)行本地事務(wù)。這樣的本地事務(wù)沒有意義,一個好的應(yīng)用服務(wù)器 將它們視為錯誤。??PlatformTransactionManager?
???org.springframework.transaction.jta.JtaTransactionManager?
???DataSource?
?
1.10. 更多資源
有關(guān) Spring 框架的事務(wù)支持的更多信息,請參閱:
- 分散式 Spring中的事務(wù),有和沒有XA是一個JavaWorld演示,其中 Spring的David Syer將引導(dǎo)您了解分布式的七種模式 Spring 應(yīng)用程序中的事務(wù),其中三個帶有 XA,四個沒有。
- 《Java事務(wù)設(shè)計策略》?是一本書 可從InfoQ獲得,提供節(jié)奏良好的介紹 到爪哇中的事務(wù)。它還包括有關(guān)如何配置的并行示例 并使用 Spring 框架和 EJB3 的事務(wù)。