对于最新的稳定版本,请使用 Spring Framework 7.0.6!spring-doc.cadn.net.cn

资源与事务同步

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

高级同步方法

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

底层同步方法

诸如 DataSourceUtils(用于 JDBC)、EntityManagerFactoryUtils(用于 JPA)、 SessionFactoryUtils(用于 Hibernate)等类存在于较低层。当您希望应用程序代码直接处理原生持久化 API 的资源类型时, 您可以使用这些类来确保获得由 Spring 框架管理的正确实例, 事务可(可选地)进行同步,并且在此过程中发生的异常会被正确映射到一致的 API。spring-doc.cadn.net.cn

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

Connection conn = DataSourceUtils.getConnection(dataSource);

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

这种方法在不使用Spring事务管理的情况下也适用(事务同步是可选的),因此无论是否使用Spring进行事务管理,你都可以使用它。spring-doc.cadn.net.cn

当然,一旦你使用了Spring的JDBC支持、JPA支持或Hibernate支持,你通常会更倾向于不使用DataSourceUtils或其他辅助类,因为通过Spring抽象来工作会让你更加愉快,而不是直接使用相关API。例如,如果你使用Spring的JdbcTemplatejdbc.object包来简化JDBC的使用,后台会正确地获取连接,你无需编写任何特殊代码。spring-doc.cadn.net.cn

TransactionAwareDataSourceProxy

在最底层存在 TransactionAwareDataSourceProxy 类。它作为目标 DataSource 的代理,通过封装目标 DataSource 来增加对 Spring 管理事务的感知能力。在这方面,它类似于由 Jakarta EE 服务器提供的事务型 JNDI DataSourcespring-doc.cadn.net.cn

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