Операции со швами

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();
    }

}
Другие вопросы по тегам