事務資源同步

現在應該清楚如何建立不同的事務管理器以及它們如何連結到需要與事務同步的相關資源(例如,DataSourceTransactionManager 到 JDBC DataSourceHibernateTransactionManager 到 Hibernate SessionFactory 等)。本節描述了應用程式程式碼(直接或間接,透過使用持久化 API,例如 JDBC、Hibernate 或 JPA)如何確保正確建立、重用和清理這些資源。本節還討論瞭如何透過相關的 TransactionManager(可選地)觸發事務同步。

高階同步方法

首選方法是使用 Spring 最高級別的基於模板的持久化整合 API,或者使用事務感知的 FactoryBean 或代理管理本地資源工廠,從而使用本地 ORM API。這些事務感知的解決方案在內部處理資源的建立和重用、清理、資源的可選事務同步以及異常對映。因此,使用者資料訪問程式碼無需處理這些任務,只需專注於非樣板式的持久化邏輯。通常,您可以使用本地 ORM API 或透過使用 JdbcTemplate 採用模板方法進行 JDBC 訪問。這些解決方案將在本參考文件的後續章節中詳細介紹。

低階同步方法

諸如 DataSourceUtils(用於 JDBC)、EntityManagerFactoryUtils(用於 JPA)、SessionFactoryUtils(用於 Hibernate)等類位於較低級別。當您希望應用程式程式碼直接處理本地持久化 API 的資源型別時,您可以使用這些類來確保獲得正確的 Spring Framework 管理的例項,事務得到(可選)同步,並且過程中發生的異常被正確地對映到一致的 API。

例如,對於 JDBC,您可以使用 Spring 的 org.springframework.jdbc.datasource.DataSourceUtils 類,而不是傳統的 JDBC 呼叫 DataSource 上的 getConnection() 方法的方法,如下所示

Connection conn = DataSourceUtils.getConnection(dataSource);

如果現有事務已經同步(連結)了一個連線,則返回該例項。否則,該方法呼叫將觸發建立新連線,該連線(可選地)與任何現有事務同步,並在同一事務中可供後續重用。如前所述,任何 SQLException 都被包裝在 Spring Framework 的 CannotGetJdbcConnectionException 中,它是 Spring Framework 非檢查型 DataAccessException 型別層次結構中的一種。這種方法提供了比從 SQLException 輕鬆獲得的資訊更多,並確保了跨資料庫甚至跨不同持久化技術的移植性。

這種方法在沒有 Spring 事務管理(事務同步是可選的)的情況下也有效,因此無論您是否使用 Spring 進行事務管理,都可以使用它。

當然,一旦您使用了 Spring 的 JDBC 支援、JPA 支援或 Hibernate 支援,通常更傾向於不使用 DataSourceUtils 或其他輔助類,因為透過 Spring 抽象進行工作比直接使用相關 API 更令人滿意。例如,如果您使用 Spring JdbcTemplatejdbc.object 包來簡化 JDBC 的使用,正確的連線檢索會在幕後發生,您無需編寫任何特殊程式碼。

TransactionAwareDataSourceProxy

在最低級別存在 TransactionAwareDataSourceProxy 類。它是目標 DataSource 的代理,它包裝了目標 DataSource 以新增對 Spring 管理的事務的感知。在這方面,它類似於 Jakarta EE 伺服器提供的事務性 JNDI DataSource

您幾乎不應該需要或想要使用此類,除非必須呼叫現有程式碼並傳遞一個標準的 JDBC DataSource 介面實現。在這種情況下,這段程式碼可能是可用的,但它參與了 Spring 管理的事務。您可以使用前面提到的更高級別抽象來編寫新程式碼。