Где именно соблюдается демаркация транзакций JTA для CMT?

Я пытаюсь полностью понять разграничение JTA с CMT. Поведение, которое я испытываю, заключается в том, что в EJB соблюдается только первый @TransactionAttribute метода, а последующие вызовы метода того же компонента с разными аннотациями @TransactionAttribute не учитываются.

Пример:

@Stateless
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class Foo implements IFoo {

   @EJB
   private IBar barBean;

   // inherits class transaction annotation of NOT_SUPPORTED
   public void doSomething() {
        barBean.doAction();
   }
}

@Stateless
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class Bar implements IBar {

    public void doAction() {
        Entity entity = bar.find();
        entity.setName("new name");
        // fails with EJBException with TransactionRequiredException as cause
        save(entity);
    }

    public Entity find() {
        // return some persisted entity.
        return em.findById(1);
    }

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public Entity save(entity) {
        em.persist(em.merge(entity));
        em.flush();
    }
}

Поведение, которое я вижу, заключается в том, что Bar.save() генерирует исключение TransactionRequiredException. Итак, это говорит мне, что аннотация REQUIRED, установленная в save(), не создает транзакцию. REQUIRES_NEW тоже не работает. Если я перенесу save() в другой EJB, он будет работать, как и ожидалось.

Означает ли это, что учитывается только первая аннотация TransactionAttribute независимо от последующих вызовов метода для того же с другими значениями аннотации? Это ошибка или ожидаемое поведение? Кажется, я не могу найти документацию, которая конкретно объясняет это. Я ценю любое понимание этого.

Мой стек: EJB 3.0, Toplink Essentials, GF V2UR2


person Hoon    schedule 08.10.2009    source источник


Ответы (1)


Мое прочтение спецификации EJB 3 состоит в том, что спецификация транзакции для отдельного метода переопределяет спецификацию EJB в целом. Поэтому ваши ожидания, что REQUIRED должен применяться, кажутся разумными, но...

это только в том случае, если вы используете метод компонента в качестве EJB. Когда вы делаете прямой вызов из одного бизнес-метода doAction() в другой, save(), вы не используете ссылку EJB, и, следовательно, это просто старая добрая Java - контейнер не задействован, поэтому у контейнера нет возможности вмешиваться .

Если вы примените требуемую опцию к методу doAction(), я ожидаю, что это сработает.

Эта теория согласуется с вашими выводами о влиянии рефакторинга на другой EJB.

person djna    schedule 08.10.2009
comment
djna - Спасибо за ответ. Ваше объяснение имеет смысл. Мне удалось связаться с другим коллегой, и он также согласился с вашим утверждением. Я ценю ваше время. - person Hoon; 09.10.2009