Откат транзакции JPA завершается неудачно с вызовом bean-компонента без сохранения состояния - PullRequest
4 голосов
/ 09 декабря 2011

Внутри 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
}

The RandomEJB:

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

1 Ответ

3 голосов
/ 09 декабря 2011

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

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

Итак:

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