Операции со швами - PullRequest
2 голосов
/ 15 июля 2010

Seam рекомендует использовать Extended постоянный контекст в Stateful Session Bean, чтобы иметь управляемое 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)ТРЕБУЕТСЯ).Таким образом, наши транзакции обрабатываются контейнером (WebLogic), а не Seam.

Однако теперь нам необходимо выполнить следующий сценарий: нам необходим внешний компонент Seam ( non-EJB ) вызывает несколько методов DAO (EJB) и объединяет их все в одну транзакцию.Если я правильно понимаю, нам нужны транзакции, управляемые Seam.

Можем ли мы иметь транзакции, управляемые Seam, как в описанном мной сценарии, без контекста персистентности, управляемого Seam?Или эти два не имеют отношения?

1 Ответ

2 голосов
/ 16 июля 2010

Как сказал

Нам нужно, чтобы интерфейсный компонент 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();
    }

}
...