跳到主要内容

使用事务同步资源

ChatGPT-4o 中英对照 Synchronizing Resources with Transactions

如何创建不同的事务管理器以及它们如何链接到需要与事务同步的相关资源(例如,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);
java

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

这种方法也适用于没有 Spring 事务管理的情况(事务同步是可选的),因此无论是否使用 Spring 进行事务管理,你都可以使用这种方法。

当然,一旦你使用了 Spring 的 JDBC 支持、JPA 支持或 Hibernate 支持,你通常更愿意通过 Spring 的抽象层来工作,而不是直接使用相关的 API,因此你一般不会使用 DataSourceUtils 或其他辅助类。例如,如果你使用 Spring 的 JdbcTemplatejdbc.object 包来简化 JDBC 的使用,正确的连接检索会在后台自动进行,你无需编写任何特殊代码。

TransactionAwareDataSourceProxy

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

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