【问题标题】:Transaction needed if multiple EJB methods called?如果调用多个 EJB 方法需要事务吗?
【发布时间】:2015-01-11 12:34:59
【问题描述】:

我的问题是,如果调用多个 EJB 方法,是否需要在 JSF Bean 中定义 UserTransaction。 这是我的一般情况:

//jsf bean...
@EJB ejb1;
...
public String process(businessobject) {
  ejb1.op1(businessobject);
  ejb1.op2(businessobject);
  ....
}

两个 ejbs 方法都操作同一个复杂的 jpa 实体 bean 对象(包括刷新和分离)。我在数据库中认识到,当在 ejb1.op2() 之前调用 ejb1.op1() 时,一些 @oneToMany 关系形成了我的实体 bean,这些关系在重复。 我了解两个 ejb 都开始了新事务。对我来说,到目前为止一切都很好。 但是只有当我像这样将 UserTransaction 添加到我的 jsf 方法中时,JSF 代码才能正常工作:

//jsf bean...
@Resource UserTransaction tx;
@EJB ejb1;
...
public String process(businessobject) {
  try {
    tx.begin();
    ejb1.op1(businessobject);
    ejb1.op2(businessobject);
  finaly {
      tx.commit();
  }....
}

我没想到有必要将两个 ejb 调用封装到一个用户事务中。为什么需要这样做?

【问题讨论】:

    标签: jpa jsf-2 transactions ejb


    【解决方案1】:

    来自客户端(在您的情况下为 JSF 托管 bean)的每个 @Stateless EJB 方法调用,默认情况下确实计为一个完整事务。这一直持续到 EJB 方法调用返回,包括嵌套的 EJB 方法调用

    如果必须表示单个事务,只需将它们合并为单个 EJB 方法调用。

    public String process(Entity entity) {
        ejb1.op1op2(entity);
        // ...
    }
    

    public void op1op2(Entity entity) {
        op1(entity);
        op2(entity);
    }
    

    无需在客户端中摆弄UserTransaction。在设计良好的基于​​ JSF 的客户端应用程序中,您也不应该需要它。

    关于事务的原因,它会锁定数据库,以防您对实体执行业务操作。您的错误是您完全分开执行了两个明显依赖的业务操作。这可能在高并发系统中确实会导致您遇到的 DB 状态损坏。

    关于交易的原因,这可能是一个很好的阅读:When is it necessary or convenient to use Spring or EJB3 or all of them together?

    【讨论】:

    • 感谢您的解释。这正是我所怀疑的。我会将调用放在一个单独的 ejb 方法/事务中。很少发生的奇怪行为现在已经消失了。我一直认为一个 JSF 方法也会启动一个新的事务上下文。
    【解决方案2】:

    您需要用户交易吗?一般来说,容器管理的事务已经足够好并且可以达到目的。

    即使您需要用户管理事务,将事务管理逻辑与 JSF 逻辑混合也不是一件好事。

    对于使用容器管理的事务,您应该考虑在 EJB 上使用 @TransactionAttribute。

    如果您的 ejb 中的所有方法都需要具有相同级别的事务支持,您可以在类级别使用注解。否则,您还可以对每个单独的 ejb 方法使用 @TransactionAttribute 注释。

    【讨论】:

      猜你喜欢
      • 2011-09-24
      • 2010-12-29
      • 1970-01-01
      • 2010-09-30
      • 1970-01-01
      • 2015-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多