JPA事务回滚失败,并调用无状态Bean [英] JPA transaction rollback fails with call to stateless bean

查看:145
本文介绍了JPA事务回滚失败,并调用无状态Bean的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在BMT内(使用UserTransaction),我在另一个无状态EJB上调用了一个方法.当我回滚此事务时,不会回滚在EJB方法中创建的实体.我将EJB 3.1与JPA 2.0一起使用.事务从方法doTheTransaction()开始:

Inside a BMT (using a UserTransaction) I call a method on another stateless EJB. When I rollback this transaction, the entity created in the EJB method is not rolled back. I use EJB 3.1 with JPA 2.0. The transaction begins in method 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
}

RandomEJB:

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的必要部分:

To be complete, here is the essential part of 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:

If you are interested, this is my 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中创建的实体,而直接在事务内部创建的实体呢?

Why is the entity created in RandomEJB not rolled back, while the entity created directly inside the transaction is?

也许这篇文章是相关的,但我真的不明白给出的答案.

Maybe this post is related, but I really don't understand the answer given.

发现错误:用@TransactionManagement(TransactionManagementType.BEAN)注释RandomEJB.我的理解是BMT事务不会通过其他带BMT注释的方法传播,而是创建了一个新事务.那可以成功,而初始事务可能失败并回滚.我猜您在使用带BMT/CMT注释的方法时需要格外小心.有人可以确认吗?

found the error: annotating RandomEJB with @TransactionManagement(TransactionManagementType.BEAN). My understanding is that BMT transactions are not propagated through other BMT annotated methods, instead a new transaction is created. That one can succeed while the initial transaction can fail and rollback. I guess you need to be carefull when using BMT/CMT annotated methods. Can someone confirm this?

推荐答案

就像您说的那样-BMT Bean不彼此共享事务.

It's just like you said - BMT beans are not sharing the transaction with each other.

这意味着您不能重用在另一个BMT中显式启动的事务. BMT就像我知道游戏的意义,我自己管理交易事务".

This means that you cannot reuse transaction you explicitly started in another BMT. BMT is like "I know what the game is about, I'll manage the transactional stuff myself".

所以:

  • BMT-> BMT将不共享交易
  • BMT-> CMT将共享交易(CMT将使用实际的交易-它不在乎容器是由用户启动还是由用户启动的-它只对交易是否存在感兴趣).
  • BMT -> BMT will not share transaction
  • BMT -> CMT will share transaction (CMT will use the actual transaction - it doesn't care if it's container started or user-started - it's just interested in fact that the transaction exist).

这篇关于JPA事务回滚失败,并调用无状态Bean的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆