事务资源同步

现在应该清楚如何创建不同的事务管理器以及它们如何与需要同步到事务的相关资源(例如 DataSourceTransactionManager 到 JDBC DataSourceHibernateTransactionManager 到 Hibernate SessionFactory 等)链接。本节描述应用程序代码(直接或间接,通过使用 JDBC、Hibernate 或 JPA 等持久化 API)如何确保这些资源被正确创建、重用和清理。本节还讨论了如何通过相关的 TransactionManager(可选地)触发事务同步。

高级同步方法

首选方法是使用 Spring 最高级的基于模板的持久化集成 API,或者使用带有事务感知工厂 Bean 或代理的原生 ORM API 来管理原生资源工厂。这些事务感知解决方案在内部处理资源的创建和重用、清理、资源的(可选)事务同步以及异常映射。因此,用户数据访问代码不必处理这些任务,而可以纯粹专注于非样板持久化逻辑。通常,您使用原生 ORM API 或通过使用 JdbcTemplate 来采用 JDBC 访问的模板方法。这些解决方案将在本参考文档的后续章节中详细介绍。

低级同步方法

在较低级别存在诸如 DataSourceUtils(用于 JDBC)、EntityManagerFactoryUtils(用于 JPA)、SessionFactoryUtils(用于 Hibernate)等类。当您希望应用程序代码直接处理原生持久化 API 的资源类型时,您可以使用这些类来确保获取正确的 Spring Framework 管理实例,(可选地)同步事务,并正确地将过程中发生的异常映射到一个一致的 API。

例如,在 JDBC 的情况下,您可以不使用传统的 JDBC 方法调用 DataSource 上的 getConnection() 方法,而是使用 Spring 的 org.springframework.jdbc.datasource.DataSourceUtils 类,如下所示:

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 管理的事务。您可以通过使用前面提到的更高级别抽象来编写新代码。