Откат транзакции JPA завершается с ошибкой при вызове bean-компонента без сохранения состояния

Внутри BMT (используя UserTransaction) я вызываю метод другого EJB без сохранения состояния. Когда я откатываю эту транзакцию, сущность, созданная в методе EJB, не откатывается. Я использую EJB 3.1 с JPA 2.0. Транзакция начинается в методе doTheTransaction():

@Stateless
@LocalBean
@TransactionManagement(TransactionManagementType.BEAN)
public class TaskExecutor {

    @Inject private SomeEntityFacade someEntityEJB;
    @Inject private RandomEJB randomEJB;
    @Resource private UserTransaction ut;

    @Asynchronous
    public Future<String> doTheTransaction () { // we start here

        try {
            SomeEntity someEntity = new SomeEntity();
            someEntityEJB.create(someEntity); // this entity is rolled back

            // call another EJB to create a SomeEntity, this entity is not rolled back
            randomEJB.createSomeEntity();

            // cause error for test
            int i = 5 / 0;

            ut.commit();
        } catch (java.lang.ArithmeticException e) {
            ut.rollback();
        }
    }
    // Omitted exceptions thrown by UserTransaction methods because they give no problems
}

СлучайныйEJB:

@Stateless
@LocalBean
@TransactionManagement(TransactionManagementType.BEAN)
public class RandomEJB {

    @Inject private SomeEntityFacade someEntityEJB;

    public void createSomeEntity () {
        // same code to create entity as in TaskExecutor:
        SomeEntity someEntity = new SomeEntity();
        someEntityEJB.create(someEntity);
    }
}

Чтобы быть полным, вот основная часть SomeEntity:

@Stateless
@LocalBean
public class SomeEntityFacade {

    @PersistenceContext(unitName = "com.mysite.PU")
    private EntityManager em;

    public void create (SomeEntity p_someEntity) {
        em.persist(p_someEntity);
    }

Если вам интересно, это мой файл persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
    <persistence-unit name="com.mysite.PU" transaction-type="JTA">
    <jta-data-source>jdbc/myDatabase</jta-data-source>
    <properties></properties>
    </persistence-unit>
</persistence>

Почему сущность, созданная в RandomEJB, не откатывается, а сущность, созданная непосредственно внутри транзакции, откатывается?

Возможно, это сообщение связано, но я действительно не понимаю данный ответ.

Изменить: обнаружена ошибка: добавление RandomEJB к @TransactionManagement(TransactionManagementType.BEAN). Насколько я понимаю, транзакции BMT не распространяются через другие аннотированные методы BMT, вместо этого создается новая транзакция. Это может быть успешным, в то время как первоначальная транзакция может потерпеть неудачу и откатиться. Я думаю, вам нужно быть осторожным при использовании аннотированных методов BMT/CMT. Кто-нибудь может это подтвердить?


person BigJ    schedule 08.12.2011    source источник
comment
Насколько я понимаю, транзакции BMT не распространяются через другие аннотированные методы BMT, вместо этого создается новая транзакция. Неа! Он не будет создан, если вы явно не создали его самостоятельно, так как это BMT. Имеет больше смысла сказать, что он будет работать без каких-либо транзакций.   -  person Bhesh Gurung    schedule 10.12.2011


Ответы (1)


Как вы и сказали, компоненты BMT не разделяют транзакцию друг с другом.

Это означает, что вы не можете повторно использовать транзакцию, которую вы явно начали в другом BMT. BMT говорит: «Я знаю, о чем игра, я сам разберусь с транзакциями».

So:

  • BMT -> BMT не разделяет транзакцию
  • BMT -> CMT будет совместно использовать транзакцию (CMT будет использовать фактическую транзакцию - ему все равно, запущен ли он контейнером или пользователем - он просто заинтересован в том, чтобы транзакция существовала).
person Piotr Nowicki    schedule 09.12.2011