使用事务同步资源

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

高级同步方法

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

低级同步方法

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

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

Connection conn = DataSourceUtils.getConnection(dataSource);

如果现有事务已同步(链接)到某个连接,则返回该实例。否则,方法调用将触发新连接的创建,该连接将(可选)同步到任何现有事务并可供在同一事务中后续重用。如前所述,任何 SQLException 都将包装在 Spring 框架的 CannotGetJdbcConnectionException 中,它是 Spring 框架的未检查 DataAccessException 类型层次结构之一。与从 SQLException 中轻松获得的信息相比,此方法提供了更多信息,并确保了跨数据库甚至跨不同持久化技术的可移植性。

此方法即使在没有 Spring 事务管理(事务同步是可选的)的情况下也能正常工作,因此无论您是否使用 Spring 进行事务管理,都可以使用它。

当然,一旦您使用了 Spring 的 JDBC 支持、JPA 支持或 Hibernate 支持,您通常不希望使用 DataSourceUtils 或其他辅助类,因为与直接使用相关 API 相比,您更愿意通过 Spring 抽象进行操作。例如,如果您使用 Spring JdbcTemplatejdbc.object 包来简化 JDBC 的使用,则正确的连接检索会在后台发生,您无需编写任何特殊代码。

TransactionAwareDataSourceProxy

在最低级别存在 TransactionAwareDataSourceProxy 类。这是目标 DataSource 的代理,它包装目标 DataSource 以添加对 Spring 管理的事务的感知。在这方面,它类似于 Jakarta EE 服务器提供的交易 JNDI DataSource

您几乎不需要也不应该使用此类,除非必须调用现有代码并传递标准 JDBC DataSource 接口实现。在这种情况下,此代码可能可用,但正在参与 Spring 管理的事务。您可以通过使用前面提到的更高级别的抽象来编写新代码。