Подтвердить что ты не робот

JEE7: Поддерживают ли EJB и CDI beans транзакции, управляемые контейнером?

Java EE7 состоит из набора определений < bean:

  • Управляемый Beans 1.0 (JSR-316/JSR-250)
  • Injection Dependency для Java 1.0 (JSR-330)
  • CDI 1.1 (JSR-346)
  • Управляемый JSF Beans 2.2 (JSR-344)
  • EJB 3.2 (JSR-345)

Чтобы избавиться от хаоса в моем сознании, я изучаю несколько статей "когда использовать тип bean". Один из плюсов для EJB кажется, что они одни поддерживают декларативные транзакции, управляемые контейнером (известные аннотации транзакций). Я не уверен, хотя, если это правильно. Кто-нибудь может это одобрить?

Между тем, я придумал простое демонстрационное приложение, чтобы проверить, действительно ли это так. Я просто определил CDI bean ( не EJB - он не имеет аннотаций уровня класса), как показано ниже, на основе этого фрагмента:

public class CdiBean {
    @Resource
    TransactionSynchronizationRegistry tsr;

    @Transactional(Transactional.TxType.REQUIRED)
    public boolean isTransactional() {
        return tsr.getTransactionStatus() == Status.STATUS_ACTIVE;
    }
}

Теперь результат GlassFish 4.0 заключается в том, что этот метод действительно возвращает true, что, согласно моим запросам, не работает как ожидалось. Я ожидал, что контейнер проигнорирует аннотацию @Transactional по методу CDI bean или даже выбросит исключение. Я использую недавно установленный сервер GlassFish 4, поэтому никаких помех нет.

Итак, мой вопрос действительно:

  • Какие типы bean действительно поддерживают транзакции, управляемые контейнером?
  • Просто ради любопытства, как я могу проверить его с помощью простого демонстрационного приложения, если неправильный код?

(BTW: Кто-то описал подобную проблему здесь, но ее решение не относится к моему делу.

4b9b3361

Ответ 1

Пока Java EE 7 только EJB не был транзакционным, а аннотация @Transactional не существовала.

Так как Java EE 7 и JTA 1.2 вы можете использовать транзакционный перехватчик в CDI с аннотацией @Transactional.

Чтобы ответить на ваш вопрос о наилучшем типе bean для использования, ответом является CDI по умолчанию.

CDI beans легче EJB и поддерживают множество функций (включая EJB) и активируются по умолчанию (при добавлении файла beans.xml к вашему приложению). Поскольку Java EE 6 @Inject заменяет @EJB. Даже если вы используете удаленные EJB (функция, не существующая в CDI), лучшая практика предполагает, что вы @EJB один раз, чтобы ввести удаленный EJB и производителя CDI, чтобы выставить его как CDI bean

public class Resources {

    @EJB
    @Produces
    MyRemoteEJB ejb;

}

То же самое предлагается для ресурсов Java EE

public class Resources2 {

    @PersistenceContext
    @Produces
    EntityManager em;

}

Эти производители будут использоваться позже

public class MyBean {

    @Inject
    MyRemoteEJB bean;

    @Inject
    EntityManager em;

}

EJB продолжает иметь смысл для определенных сервисов, которые они включают в себя как JMS или асинхронное лечение, но вы будете использовать их как CDI bean.

Ответ 2

javadoc Transactional говорит:

Аннотации javax.transaction.Transactional предоставляют приложению возможность декларативно контролировать границы транзакций на управляемом CDI beans, а также классы, определенные как управляемые beans по спецификации Java EE, как на уровне класса, так и на уровне метода где аннотации уровня метода переопределяют те, которые находятся на уровне класса.

Итак, ваши предположения ошибочны. EJB до Java EE 6 были единственными компонентами поддержки декларативных транзакций. Транзакционная аннотация точно была введена в Java EE 7, чтобы сделать транзакцию не EJB, управляемого CDI beans.