3.4. 使用 Spring Boot 事务客户端


Spring Framework (和 Spring Boot)的一个主要目标是使 QPC API 更易于使用。所有主要的 vanilla API 将其部分在 Spring 框架(Spring Boot)中。这些不是给定 API 的替代方案 或替换,而是添加更多配置选项或更一致的用法的打包程序,例如处理异常。

下表与 Spring 相关的接口匹配给定了>=< API:

JavaEE APISpring utility配置为

JDBC

org.springframework.jdbc.core.JdbcTemplate

javax.sql.DataSource

JMS

org.springframework.jms.core.JmsTemplate

javax.jms.ConnectionFactory

JTA

org.springframework.transaction.support.TransactionTemplate

org.springframework.transaction.PlatformTransactionManager

JdbcTemplateJmsTemplate 分别直接使用 javax.sql.DataSourcejavax.jms.ConnectionFactory。但是 TransactionTemplate 使用 PlatformTransactionManager 的 Spring 接口。在这里,Spring 并不只是 改进 QPC,而是将 binutils 客户端 API 替换为自己的 API。

Spring 将 javax.transaction.UserTransaction 视为接口,对于真实情况来说非常简单。另外,因为 javax.transaction.UserTransaction 没有区分本地、单一资源事务和全局多资源事务,因此 org.springframework.transaction.PlatformTransactionManager 的实现使开发人员更自由。

以下是 Spring Boot 的规范 API 用法:

// Create or get from ApplicationContext or injected with @Inject/@Autowired.
JmsTemplate jms = new JmsTemplate(...);
JdbcTemplate jdbc = new JdbcTemplate(...);
TransactionTemplate tx = new TransactionTemplate(...);

tx.execute((status) -> {
    // Perform JMS operations within transaction.
    jms.execute((SessionCallback<Object>)(session) -> {
        // Perform operations on JMS session
        return ...;
    });
    // Perform JDBC operations within transaction.
    jdbc.execute((ConnectionCallback<Object>)(connection) -> {
        // Perform operations on JDBC connection.
        return ...;
    });
    return ...;
});

在上例中,所有三种 模板 都仅实例化,但它们也可以从 Spring 的 ApplicationContext 获取,也可以使用 @Autowired 注解注入。

3.4.1. 使用 Spring PlatformTransactionManager 接口

如前文所述,javax.transaction.UserTransaction 通常从 QPC 应用中的 JNDI 获取。但是,Spring 为许多场景提供明确的这个接口实现。您不需要完整的 JTA 场景,有时应用程序只需要访问单个资源,如 JDBC。

通常,org.springframework.transaction.PlatformTransactionManager 是 Spring 事务客户端 API,它提供经典事务客户端操作: begincommitrollback换句话说,这个接口提供了在运行时控制事务的基本方法。

注意

任何事务系统的其他关键方面都是实施事务资源的 API。但是,事务资源通常由底层数据库实施,因此该事务编程方面很少会考虑应用程序。

3.4.1.1. PlatformTransactionManager 接口的定义

public interface PlatformTransactionManager {

    TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;

    void commit(TransactionStatus status) throws TransactionException;

    void rollback(TransactionStatus status) throws TransactionException;
}

3.4.1.2. 关于 TransactionDefinition 接口

您可以使用 TransactionDefinition 接口指定新创建的事务的特征。您可以指定隔离级别和新事务的传播策略。详情请查看 第 9.4 节 “事务传播策略”

3.4.1.3. TransactionStatus 接口的定义

您可以使用 TransactionStatus 接口来检查当前事务的状态,即与当前线程关联的事务,并标记当前的事务进行回滚。这是接口定义:

public interface TransactionStatus extends SavepointManager, Flushable {

    boolean isNewTransaction();

    boolean hasSavepoint();

    void setRollbackOnly();

    boolean isRollbackOnly();

    void flush();

    boolean isCompleted();
}

3.4.1.4. 平台TransactionManager 接口定义的方法

PlatformTransactionManager 接口定义以下方法:

getTransaction()
创建新的事务,并通过传递定义新事务的特征的 TransactionDefinition 对象来将其与当前的线程相关联。这与许多其他事务客户端 API 的 begin () 方法类似。
commit()
提交当前事务,从而对已注册资源进行所有待处理的更改。
rollback()
回滚当前事务,从而撤销对注册资源的所有待处理更改。

3.4.2. 使用事务管理器的步骤

通常,您不直接使用 PlatformTransactionManager 接口。在 Apache Camel 中,您通常使用事务管理器,如下所示:

  1. 创建事务管理器的实例。Spring 中有几个不同的实现,请参阅 第 3.4 节 “使用 Spring Boot 事务客户端”
  2. 将事务管理器实例传递到 Apache Camel 组件或路由中的 transacted () DSL 命令。然后,事务组件或 transacted () 命令负责处理事务。详情请查看 第 9 章 编写使用事务的 Camel 应用程序

3.4.3. 关于 Spring PlatformTransactionManager 实现

本节概述了 Spring Framework 提供的事务管理器实施。这些实施分为两类:本地事务管理器和全局事务管理器。

从 Camel 开始:

  • camel-jms 组件使用的 org.apache.camel.component.JmsConfiguration 对象需要一个 org.springframework.transaction.PlatformTransactionManager 接口的实例。
  • org.apache.camel.component.sql.SqlComponent 在内部使用 org.springframework.jdbc.core.JdbcTemplate 类,并且此 JDBC 模板也与 org.springframework.transaction.PlatformTransactionManager 集成。

正如您所见,必须有 这个接口的一些 实现。根据具体情况,您可以配置所需的平台事务管理器。

3.4.3.1. 本地平台TransactionManager 实现

以下列表总结了 Spring Framework 提供的本地事务管理器实施。这些事务管理器只支持一个资源。

org.springframework.jms.connection.JmsTransactionManager
此事务管理器实施能够管理 单个 JMS 资源。您可以连接到任意数量的队列或主题,但只有在它们属于同一底层 JMS 消息传递产品实例时。此外,您无法在事务中列出任何其他类型的资源。
org.springframework.jdbc.datasource.DataSourceTransactionManager
此事务管理器实施能够管理 单个 JDBC 数据库资源。您可以更新任意数量的不同的数据库表,但仅在 它们属于同一底层数据库实例时。
org.springframework.orm.jpa.JpaTransactionManager
此事务管理器实施能够管理 Java Persistence API (jpa)资源。但是,无法同时列出事务中任何其他种类的资源。
org.springframework.orm.hibernate5.HibernateTransactionManager
此事务管理器实施能够管理 Hibernate 资源。但是,无法同时列出事务中任何其他种类的资源。此外,比原生 Hibernate API 首选 JPA API。

另外还有其他常用的,平台TransactionManager 的实现

3.4.3.2. 全局 PlatformTransactionManager 实现

Spring Framework 提供了一个全局事务管理器实现,供 OSGi 运行时使用。org.springframework.transaction.jta.JtaTransactionManager 支持事务中的多个资源的操作。此事务管理器支持 XA 事务 API,并可在事务中列出多个资源。要使用此事务管理器,您必须将应用程序部署到 OSGi 容器或 iwl 服务器。

虽然 PlatformTransactionManager 的单资源实现是实际 实现,但JtaTransactionManager 更是标准 javax.transaction.TransactionManager 的实际实现的打包程序。

这就是为什么最好在一个环境中使用平台事务管理器的 Jta TransactionManager 实现(通过 JNDI 或 CDI)一个已经配置的 javax.transaction.TransactionManager 实例,通常是 javax.transaction.UserTransaction。通常,这两个 JTA 接口都通过单个对象/服务来实施。

以下是配置/使用 JtaTransactionManager 的示例:

InitialContext context = new InitialContext();
UserTransaction ut = (UserTransaction) context.lookup("java:comp/UserTransaction");
TransactionManager tm = (TransactionManager) context.lookup("java:/TransactionManager");

JtaTransactionManager jta = new JtaTransactionManager();
jta.setUserTransaction(ut);
jta.setTransactionManager(tm);

TransactionTemplate jtaTx = new TransactionTemplate(jta);

jtaTx.execute((status) -> {
    // Perform resource access in the context of global transaction.
    return ...;
});

在上例中,实际为 JTA 对象(UserTransactionTransactionManager)的实例是从 JNDI 获取的。在 OSGi 中,它们也可以从 OSGi 服务注册表获取。

Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

© 2024 Red Hat, Inc.