2

Seam 建议在有状态会话 Bean 中使用扩展的持久性上下文,以便拥有 Seam 管理的持久性。

我不清楚上述建议是否会对我们希望拥有 Seam 管理的交易的方式产生任何影响。这是因为我们的架构不同。我们在无状态EJB中有以下持久性上下文:

@Stateless
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class CrudServiceBean implements CrudService {

    @PersistenceContext(type = PersistenceContextType.TRANSACTION)
    private EntityManager em;
...
}

我们的 DAO 调用上述 CrudServiceBean 是带有 @TransactionAttribute(TransactionAttributeType.REQUIRED) 的无状态 EJB(其中一些也是 Seam 组件)。因此,我们的事务由容器(WebLogic)而不是 Seam 处理。

但是,我们现在需要满足以下场景:我们需要一个前端 Seam 组件(非 EJB)调用多个 DAO (EJB) 方法并将所有这些方法包装在一个事务中。如果我理解正确,我们需要有 Seam 管理的事务。

我们可以像我描述的场景那样拥有 Seam 管理的事务,而没有 Seam 管理的持久性上下文吗?还是两者无关?

4

1 回答 1

2

如前所述

我们需要有一个前端 Seam 组件(非 EJB)调用多个 DAO (EJB) 方法并将它们全部包装在一个事务中

我们的事务由容器处理- 也称为容器管理事务(容器负责调用每个底层资源管理器事务使用的开始和提交方法)

第一个问题是您有一个非 EJB 调用多个 DAO 的场景,每个 DAO 都是一个 EJB。你可以想到

@Name("nonEjbComponent")
public class NonEjbComponent {

    private @In DaoEjbComponent daoEjbComponent;
    private @In OtherDaoEjbComponent otherDaoEjbComponent;
    private @In AnotherDaoEjbComponent anotherDaoEjbComponent;

    private @In UserTransaction userTransation;

    public void wrapperAllOfThem() {

         userTransation.begin();

             daoEjbComponent.save(someEntity);
             otherDaoEjbComponent.update(otherEntity);
             anotherDaoEjbComponent.delete(anotherEntity);

         userTransation.commit();

    }

}

但是 Java EE 规范 3.0 指出

具有 bean 管理或容器管理的事务划分的企业 bean必须是会话 bean 或消息驱动的 bean

所以你不能使用上面的场景。而且因为你所有的 DAO 都使用容器管理的事务,Java EE 规范不允许你同时使用容器管理和 bean 管理的事务

所以解决方案是

将所有 DAO 包装在一个 EJB 无状态会话 bean 中,该会话 bean的事务是容器管理的。它将表现得像一个委托组件

@Stateless
@TransactionAttribute(TransactionAttributeType.REQUIRED)
@Name("wrapperStateless")
public class WrapperStatelessImpl implements WrapperStateless {

    private @In DaoEjbComponent daoEjbComponent;
    private @In OtherDaoEjbComponent otherDaoEjbComponent;
    private @In AnotherDaoEjbComponent anotherDaoEjbComponent;

    public void wrapperAllOfThem() {

        daoEjbComponent.save(someEntity);
        otherDaoEjbComponent.update(otherEntity);
        anotherDaoEjbComponent.delete(anotherEntity);

    }

}

在您的非 EJB 组件中,使用

@Name("nonEjbComponent")
public class NonEjbComponent {

    private @In WrapperStateless wrapperStateless;

    public void wrapperAllOfThem() {
        wrapperStateless.wrapperAllOfThem();
    }

}
于 2010-07-16T06:00:47.833 回答