Управление транзакциями CDI

Я работаю над проектом миграции с JBoss Seam на CDI. Ниже приведен стек технологий:

1) WildFly 8.2.0 (CDI 1.2 с Weld в качестве поставщика CDI)

2) JSF 2.2

3) JPA 2

Мы используем JTA-транзакции, управляемые контейнером:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
   xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="
        http://xmlns.jcp.org/xml/ns/persistence
        http://xmlns.jcp.org/xml/ns/persistence/persistence@PersistenceContext1.xsd">
   <persistence-unit name="surveillenace" transaction-type="JTA">
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    <jta-data-source>java:/surveillenaceDS</jta-data-source> 


    <!-- other configurations not shown here -->

</persistence>

и используя аннотацию @PersistenceContext для внедрения EntityManager в объект DAO.

Мы используем аннотацию @Transaction для транзакций, управляемых контейнером.

Мои вопросы / понимание приведены ниже.

Кто-нибудь может подтвердить это, так как это относительно новая для меня область.

1) Насколько я понимаю, CDI обеспечивает поддержку CMT через перехватчик @Transaction. Какой класс / зависимость действительно реализует этот перехватчик? Какие артефакты нам нужно для этого импортировать в pom.xml?

2) Поскольку используется CMT, нам не нужно разграничивать транзакцию, и контейнер будет управлять ею. Нам нужно только использовать EntityManager API для сохранения изменений в Db. Это понимание правильное?

 @Transactional
    public String finishOperation() {
        log.debug("in finishOperation() ") ;
        try {   
        //operations done on managed entities 
        //no transaction demarcation code is required here 
        dao.getEntityManager.commit();      

    }catch(Throwable xx){
    }
    }

3) Рассмотрим нижеприведенный тривиальный сценарий, выполненный с использованием указанной выше конфигурации:

Component1.somemethod() - выполняется внутри транзакции и сохраняет сущность (например, пользователя) и фиксирует транзакцию. После этого вызывается Component2, как показано ниже:
Component2.somemethod() - выполняется внутри преобразования, но объект User, похоже, не находится в управляемом состоянии, то есть em.contains(user) возвращает false. Мне нужно снова объединить этот объект, чтобы он стал управляемым, или снова перезагрузить его из постоянного хранилища.

Поскольку Seam использует conversation-scoped entity manager, все экземпляры сущностей остаются в управляемом состоянии (внутри постоянного контекста), даже когда какой-либо компонент фиксирует транзакцию и после этого вызывается другой компонент. Но в случае с CDI, насколько я понимаю, это происходит из-за "transaction scoped entity manager". После фиксации транзакции все экземпляры сущности отсоединяются. Как мы можем добиться того же эффекта, что и Seam, используя CDI?


person Atul    schedule 06.07.2015    source источник


Ответы (2)


Чтобы ответить на ваш вопрос и уточнить предыдущий ответ, который был нацелен только на Java EE 6 / CDI 1.0, пока вы работаете с Java EE 7 / CDI 1.2

  1. CDI не реализует транзакцию, но спецификация JTA делает. Да JTA определяет привязку перехватчика @Transactional, и реализация должна предоставить соответствующие перехватчики. Поскольку вы находитесь под WildFly, ответ на ваш вопрос находится в реализации JBoss JTA: Narayana. Вы найдете @Transactional(Required) перехватчик здесь. Остальные находятся в том же пакете.
  2. Да, ваше понимание правильное.
  3. Контекст Extended Persistence может быть введен только в сессионном компоненте EJB с отслеживанием состояния. В Java EE 7 вы можете попробовать использовать новый режим JPA 2.1 Unsyncrhonized (не тестировался в CDI).
person Antoine Sabot-Durand    schedule 08.07.2015
comment
конечно, вы правы, я исправлюсь, я понимаю, что J EE 7 предоставляет @Transactional перехватчик. Я по какой-то причине думал о CDI 1.0, я думаю, извините за какой-то дезинформирующий ответ - person mariubog; 08.07.2015

CDI не предоставляет реализацию управления транзакциями как часть своих спецификаций. Управление транзакциями остается реализовывать программисту через перехватчики, которые позаботятся обо всех основах, таких как начало фиксации и т. Д.

Обычно EntityManager живет во временном интервале транзакции. В шве 2 у вас был расширенный контекст персистентности, поэтому он сохранял состояние и bean-компоненты, прикрепленные к нему, по нескольким запросам. CDI не предоставляет этого, более того, не рекомендует это по причинам масштабируемости. Если вы посмотрите на DeltaSpike, который я настоятельно рекомендую в случае перехода с Seam2 на CDI, они предлагают возможность продления срока службы EntityManager, продвигая его в область диалога, но они также не рекомендуют этот подход.


Здесь у вас есть документы, чтобы DeltaSpike решила вашу проблему:

https://deltaspike.apache.org/documentation/jpa.html#ExtendedPersistenceContexts

Deltaspike - отличное решение для связывания, а документация очень короткая, поэтому я бы порекомендовал ее в вашем случае, кроме того, она создается людьми со швом и обеспечивает управление транзакциями из коробки.

person mariubog    schedule 07.07.2015
comment
Ваш ответ верен в отношении Java EE 6, но неверен в Java EE 7. JTA 1.2 предоставляет @Transactional привязку перехватчика, а также реализацию перехватчика. - person Antoine Sabot-Durand; 08.07.2015