Bezdepbonusu7Программирование: статьи и ответы

Вопрос

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

Автор вопроса: BigJОтветов: 1

Внутри 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. Кто-нибудь может это подтвердить?

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

persistencetransactionsjparollback

Ответы

Ответ 1 · рейтинг 4 · Piotr Nowicki

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

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

So:

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

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы