我有一个有状态EJB,其中一个事务性@Asynchronous
方法返回Future<T>
。它是从web-tier(@SessionScoped
CDI bean)调用的,如下所示:
@SessionScoped
@Named
public class SessionBean {
@EJB
EjbService service
public void call() {
Future<Object> response = service.process();
}
}
@Stateful
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class EjbService {
@Asynchronous
public Future<Object> process() {
//
}
}
问题是如果用户在执行此异步调用期间终止Web会话,事务会发生什么?
答案 0 :(得分:1)
@Asynchronous
方法创建一个新事务(即使该类具有另一个属性,TransactionAttributeType.REQUIRED
仍将创建一个新事务)。
现在,如果在get()
中调用Future<V>
方法,则线程将等到AsyncResult在计算结束时变为可用。之后,Stateful可以执行超时并将被容器销毁。
如果你只是执行Async方法 - 没有get()
- ,那么该方法将被排队并处理,然后同样适用......状态被破坏。
专业提示:ejb容器维护完成异步调用的结果值一段时间(此时间未在规范中定义)。
总而言之,因为发生了一个新事务,并且控件立即返回给客户端(除非调用get()
),所以事务在正常情况下没有例外地完成。