11.7. 练习中的事务使用
11.7.1. 事务使用情况概述
当您需要在应用中使用事务时,以下步骤非常有用。
11.7.2. 控制事务
简介
本流程列表概述了控制应用中使用 Jakarta Transactions API 的不同方法。
11.7.2.1. 开始交易
此流程演示了如何开始新交易。无论您运行配置了 Jakarta Transactions 或 JTS 的事务管理器™,API 都相同。
- 获取 - UserTransaction实例.- 如果 Jakarta Enterprise Beans 使用 - @TransactionManagement(TransactionManagement)注释(TransactionManagementType.BEAN)注释,则可以使用 Java 命名和目录接口、注入或 Jakarta Enterprise Beans 上下文获取实例。- 使用 Java 命名和目录界面获取实例。 - new InitialContext().lookup("java:comp/UserTransaction")- new InitialContext().lookup("java:comp/UserTransaction")- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
- 使用注入获取实例。 - @Resource UserTransaction userTransaction; - @Resource UserTransaction userTransaction;- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
- 使用 Jakarta Enterprise Beans 上下文获取实例。 - 在无状态/状态 Bean 中: - @Resource SessionContext ctx; ctx.getUserTransaction(); - @Resource SessionContext ctx; ctx.getUserTransaction();- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
- 在消息驱动型 Bean 中: - @Resource MessageDrivenContext ctx; ctx.getUserTransaction() - @Resource MessageDrivenContext ctx; ctx.getUserTransaction()- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
 
 
- 连接到数据源后,请致电 - UserTransaction.begin()。- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
结果
事务开始。在提交或回滚事务之前,数据源的所有用途都是事务性。
有关完整示例,请参阅 Jakarta Transactions 交易示例。
Jakarta Enterprise Beans(用于 CMT 或 BMT)的好处之一是,容器管理事务处理的所有内部,也就是说,您可以免于处理作为 JBoss EAP 容器中 XA 事务处理一部分的事务处理或事务分配。
11.7.2.1.1. 嵌套事务
嵌套交易允许应用创建嵌入在现有事务中的事务。在此模型中,多个子事务可以递归地嵌入到事务中。子事务可以提交或回滚,无需提交或回滚父事务。但是,提交操作的结果取决于所有交易先锋的承诺。
有关具体实施的信息,请参阅 Narayana 项目文档。
嵌套事务仅在与 JTS 规范一起使用时才可用。嵌套事务不是 JBoss EAP 应用服务器的支持功能。此外,许多数据库供应商不支持嵌套交易,因此请在向应用添加嵌套事务前咨询您的数据库供应商。
11.7.2.2. 提交事务
此流程演示了如何使用 Jakarta Transactions 进行交易。
先决条件
您必须先开始事务,然后才能提交。有关如何开始交易的详情,请参考 开始交易。
- 对 - UserTransaction调用- commit()方法。- 当您在 - UserTransaction上调用 commit()方法时,TM 会尝试提交事务。- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
- 如果使用容器管理事务(CMT),则不需要手动提交。 - 如果将 Bean 配置为使用容器管理交易,则容器将根据您在代码中配置的注解来管理您的事务生命周期。 - Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
结果
您的数据源提交和您的事务终止,或者抛出异常。
有关完整示例,请参阅 Jakarta Transactions 交易示例。
11.7.2.3. 回滚事务
此流程演示了如何使用 Jakarta Transactions 回滚事务。
先决条件
您必须先开始事务,然后才能回滚。有关如何开始交易的详情,请参考 开始交易。
- 在 - UserTransaction上调用- rollback()方法。- 当您在 - UserTransaction上调用- rollback()方法时,TM 会尝试回滚事务并将数据返回到之前的状态。- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
- 如果使用容器管理事务(CMT),则不需要手动回滚事务。 - 如果将 Bean 配置为使用容器管理交易,则容器将根据您在代码中配置的注解来管理您的事务生命周期。 
如果抛出 RuntimeException,则 CMT 会出现回滚。您还可以显式调用 setRollbackOnly 方法以获取回滚。或者,将 @ApplicationException(rollback=true)用于回滚应用异常。
结果
您的事务由 TM 回滚。
有关完整示例,请参阅 Jakarta Transactions 交易示例。
11.7.3. 在交易中处理 Heuristic Outcome
启发式事务结果不常见,通常具有特殊的原因。神秘一词意味着"手动",这就是通常必须处理这些结果的方式。有关启发式事务结果的更多信息,请参阅关于 Heuristic Outcomes。
此流程演示了如何使用 Jakarta Transactions 处理交易的启发式结果。
- 事务中的启发式成果的原因是资源经理承诺可以提交或回滚,然后无法履行承诺。这可能是因为第三方组件、第三方组件和 JBoss EAP 之间的集成层或 JBoss EAP 本身存在问题。 - 目前,导致启发式错误的最常见两个原因是环境中的瞬态故障,以及处理资源管理器的编码错误。 
- 通常,如果您的环境中出现瞬态故障,您通常会在发现启发性错误前了解它。这可能是因为网络中断、硬件故障、数据库故障、电源中断或许多其他因素造成的。 - 如果在压力测试期间测试环境中发现了启发性的结果,这意味着您的测试环境存在缺点。 警告- JBoss EAP 自动恢复出现故障时处于非修复状态的交易,但不试图恢复启发式交易。 
- 如果您的环境中没有明显失败,或者启发式结果很容易再现,这可能是因为编码错误。您必须联系第三方供应商,以确定解决方案是否可用。 - 如果您怀疑问题在 JBoss EAP 本身的交易经理中,您必须提交支持票据。 
- 您可以使用管理 CLI 尝试手动恢复事务。如需更多信息,请参阅在 JBoss EAP 上管理交易的 恢复事务 参与者 一节。
- 手动解决事务结果的过程取决于故障的确切情况。根据您的环境执行以下步骤: - 确定涉及哪些资源管理器。
- 检查事务管理器和资源管理器的状态。
- 在一个或多个涉及的组件中手动强制进行日志清理和数据协调。
 
- 在测试环境中,或者如果您不关注数据的完整性,请删除事务日志并重新启动 JBoss EAP 将会去除启发式结果。默认情况下,事务日志位于单机服务器的 - EAP_HOME/standalone/data/tx-object-store/目录中,或者位于受管域中的- EAP_HOME/domain/servers/SERVER_NAME/data/tx-object-store/目录中。对于受管域,SERVE R_NAME 是指参与服务器组的单个服务器的名称。注意- 事务日志的位置还取决于使用的对象存储,以及为 object-store- - relative-to 和参数设置的值。对于文件系统日志,如标准 shadow 和 Apache ActiveMQ Artemis 日志,将使用默认的目录位置,但在使用 JDBC 对象存储时,事务日志存储在数据库中。- object-store-path
11.7.4. Jakarta Transactions 事务错误处理
11.7.4.1. 处理事务错误
事务错误很难解决,因为它们通常依赖于时间。以下是排除错误的一些常见错误和观点:
这些规则不适用于启发性错误。如果您遇到启发性错误,请参阅 在交易中处理 Heuristic Outcome,并联系红帽全球支持服务以获得帮助。
- 事务超时,但业务逻辑线程未注意到
- 当 Hibernate 无法获取用于延迟加载的数据库连接时,这种类型的错误通常会列出自身。如果频繁发生,您可以延长超时值。有关 配置事务管理器 的详情,请查看 JBoss EAP 配置指南。 - 如果这不可行,您或许能够调整外部环境以更快地执行,或者将代码重组为更高效。如果您遇到超时问题,请联系红帽全球支持服务。 
- 事务已在线程上运行,或者您收到 NotSupportedException 异常
- NotSupportedException 异常通常表示您试图嵌套 Jakarta Transactions 事务,且不受支持。如果您没有尝试嵌套事务,则可能会在线程池任务中启动另一个事务,但无需暂停或终止事务即可完成任务。- 应用通常使用 - UserTransaction,后者自动处理此问题。如果是这样,则框架可能存在问题。- 如果您的代码确实 - 直接使用或交易方法,请注意提交或回滚事务时的以下行为:如果您的代码使用- 事务管理器- TransactionManager方法来控制您的事务,则提交或回滚事务会从当前线程中解除事务关联。但是,如果您的代码使用- 事务方法,则事务可能不会与正在运行的线程关联,而且您需要手动将其从线程中取消关联,然后再将其返回到线程池。
- 您无法获取第二个本地资源
- 如果您尝试将第二个非 XA 资源放入事务中,则会出现这个错误。如果您在事务中需要多个资源,则必须是 XA。