正如所说的
我们需要一个前端接缝组件(
非EJB
)调用多个DAO(EJB)方法和
将它们全部包装在一个事务中
但是
我们的交易
由集装箱搬运
-也称为容器管理事务(容器
负责呼叫Begin和Commit
每个基础资源管理器事务使用的方法)
第一个问题是,您有一个场景,其中一个非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();
}
}
但是JavaEE规范3状态
具有bean管理或容器管理事务划分的企业bean
必须是会话bean或消息驱动bean
.
所以你
不能
使用上面的场景。因为所有的DAO都使用容器管理事务,JavaEE规范
不允许使用
容器管理和bean管理的事务
同时
所以解决办法是
在EJB无状态会话bean中包装所有DAO
其事务由容器管理
. 它的行为将类似于委托组件
@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();
}
}