gpt4 book ai didi

java - 事务不活动异常 - EJB 事务状态

转载 作者:行者123 更新时间:2023-12-04 05:59:44 25 4
gpt4 key购买 nike

我遇到了负责启动事务的 EJB 组件的问题。
我正在使用 Jboss 5.01。

基本上我想在提交特定事务后执行给定的代码。特定代码还涉及调用一个 EJB 组件,该组件使其成为自己的事务。

为了确保我的代码在前一个事务提交后执行,我注册了一个
同步组件变成事务组件:

Transaction tx = transactionManager.getTransaction();
tx.registerSynchronization(new CallbackSynchronization());
Synchronizaton实现基本上执行以下操作:
class CallbackSynchronization implements Synchnronization {

private AccountService service; // This is a Stateless session bean

public CallbackSynchronization(AccountService service) {
this.service = service;
}

public afterCompletion(int status) {
if(Status.STATUS_COMMITTED == status) {
service.deleteAccounts();
}
}
}

问题是当我调用 service.deleteAccounts()我得到一个异常,最终告诉我事务不活跃。

这就是让我感到困惑的地方。带有 @TransactionAttribute(TransactionAttributeType.REQUIRED) 标记的方法的 EJB如果一个事务不活动,将创建一个新事务(REQUIRED 是 JBOSS 中的默认值)。

那为什么我会得到“交易不活跃”?

非常感谢,

亚尼夫

最佳答案

问题是您启动的原始事务仍然与线程相关联(即使它处于 COMMITTED 状态)。使用 Transaction 之间的显着差异之一和 TransactionManager是后者的commit()rollback()方法将取消事务与线程的关联。从 javadoc 中引用这两种方法:

When this method completes, the thread is no longer associated with a transaction.



有两种方法可以解决这个问题(我正在以一种非常原始的方式概述它们,您可能需要对其进行一些改进)。

选项 1:针对事务管理器发出回滚或提交(在 try block 中,因为它会失败)。
public afterCompletion(int status) {
if(Status.STATUS_COMMITTED == status) {
try { transactionManager.rollback(); } catch (Throwable t) {}
service.deleteAccounts();
}
}

选项 2:启动一个新事务,这将通过预先启动一个事务来满足您的 EJB 的 REQUIRED 属性,但是您需要坚持并管理它,这会变得很棘手。
public afterCompletion(int status) {
if(Status.STATUS_COMMITTED == status) {
try {
transactionManager.begin();
service.deleteAccounts();
transactionManager.commit();
} catch (Exception e) {
// ... handle exception here
}
}
}

选项 3:最干净的选项可能是将 EJB 方法标记为 REQUIRES_NEW 因为这将强制 EJB 容器启动一个新事务。

关于java - 事务不活动异常 - EJB 事务状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9069518/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com