Операции со швами
Seam советует использовать расширенный постоянный контекст в компоненте сеанса с сохранением состояния, чтобы обеспечить управляемость Seam.
Мне не ясно, влияет ли приведенный выше совет на то, как мы хотим проводить транзакции под управлением Seam. Это потому, что наша архитектура отличается. У нас есть следующий постоянный контекст в EJB без гражданства:
@Stateless
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class CrudServiceBean implements CrudService {
@PersistenceContext(type = PersistenceContextType.TRANSACTION)
private EntityManager em;
...
}
Наши DAO вызывают вышеупомянутый CrudServiceBean - EJB без сохранения состояния (некоторые из них также являются компонентами Seam) с @TransactionAttribute(TransactionAttributeType.REQUIRED). Таким образом, наши транзакции обрабатываются контейнером (WebLogic), а не Seam.
Однако теперь нам нужно выполнить следующий сценарий: нам нужно, чтобы интерфейсный компонент Seam (не-EJB) вызывал несколько методов DAO (EJB) и объединял их все в одну транзакцию. Если я правильно понимаю, нам нужны транзакции, управляемые Seam.
Можем ли мы иметь управляемые Seam транзакции, как в описанном мною сценарии, без наличия постоянного контекста, управляемого Seam? Или два не имеют значения?
1 ответ
Как сказал
Нам нужно, чтобы внешний компонент Seam (не EJB) вызывал несколько методов DAO (EJB) и объединял их все в одну транзакцию
Но
Наши транзакции обрабатываются контейнером - также называемым управляемой контейнером транзакцией (контейнер заботится о вызове метода begin и commit, используемого каждой базовой транзакцией менеджера ресурсов)
Первая проблема заключается в том, что у вас есть сценарий, в котором не-EJB вызывает несколько 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 гласит
Корпоративный компонент с разграничением транзакций, управляемых компонентом или контейнером, должен быть компонентом сеанса или компонентом, управляемым сообщениями.
Таким образом, вы не можете использовать сценарий выше. И поскольку все ваши DAO используют транзакции, управляемые контейнером, спецификация Java EE не позволяет вам использовать транзакции, управляемые контейнером и бином, одновременно
Так что решение
Оберните все DAO в EJB-компонент сеанса без сохранения состояния , транзакция которого управляется контейнером. Он будет вести себя как компонент делегата
@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();
}
}