Откат транзакции 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
}
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 ответ
Как вы и сказали, бины BMT не делят транзакции друг с другом.
Это означает, что вы не можете повторно использовать транзакцию, которую вы явно начали в другом BMT. BMT похож на "Я знаю, о чем игра, я сам буду управлять транзакционными вещами".
Так:
- BMT -> BMT не будет делиться транзакцией
- BMT -> CMT будет делить транзакцию (CMT будет использовать фактическую транзакцию - ей все равно, запущен контейнер или запущен пользователем - просто интересует факт существования транзакции).