使用事务同步资源

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

高级同步方法

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

低级同步方法

诸如 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或其他辅助类,因为您更喜欢通过 Spring 抽象而不是直接使用相关 API 来工作。例如,如果您使用 Spring 的JdbcTemplatejdbc.object包来简化 JDBC 的使用,则连接的正确检索将在后台发生,您无需编写任何特殊代码。

TransactionAwareDataSourceProxy

在最底层存在TransactionAwareDataSourceProxy类。这是一个针对目标DataSource的代理,它包装目标DataSource以增加对 Spring 管理的事务的感知。在这方面,它类似于由 Jakarta EE 服务器提供的可事务性 JNDI DataSource

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