Jpa JTA UserTransaction回滚不起作用

Jpa JTA UserTransaction回滚不起作用,jpa,ejb,translation,jta,Jpa,Ejb,Translation,Jta,我试着简单地描述一下我的环境。技术:EJB3.1、JSF、JBoss7.1.1 存在服务类(@SessionScoped@Stateful)。服务类调用Dao类(@Stateless) 我想: 仅在@StateLess bean(Dao)中使用EntityManager 大多数情况下都有短事务(如持久、合并) 对于某些多步骤方法有一个长事务(方法也在Dao中) 具有实际(最新,无一级缓存)数据 我有: Pesistense.xml 事务拦截器 @Transactional @Interce

我试着简单地描述一下我的环境。技术:EJB3.1、JSF、JBoss7.1.1

存在服务类(@SessionScoped@Stateful)。服务类调用Dao类(@Stateless)

我想:

  • 仅在@StateLess bean(Dao)中使用EntityManager
  • 大多数情况下都有短事务(如持久、合并)
  • 对于某些多步骤方法有一个长事务(方法也在Dao中)
  • 具有实际(最新,无一级缓存)数据
我有: Pesistense.xml

事务拦截器

@Transactional
@Interceptor
public class TransactionInterceptor implements Serializable {


    @Resource
    private UserTransaction userTransaction;

    @AroundInvoke
    public Object verifyAccess(InvocationContext context) throws
            Exception {
        Object result = null;

        try {
            userTransaction.begin();
            result = context.proceed();
            userTransaction.commit();
        } catch (Exception e) {
                userTransaction.rollback();
             throw new CustomRuntimeException(e.getMessage());
        }

        return result;
    }

}
问题: 若向Dao方法抛出异常,则部分数据将保存在DB中,而不是全部回滚

我认为,需要将事务连接到EM。或者断开连接,将每个项目立即保存到DB(使用缓存)。 我尝试过不同的方法,但没有成功


提前谢谢

这看起来特别有问题:

<property name="hibernate.connection.autocommit" value="true"/>

您不应该在
persistence.xml
文件中进行任何连接管理。
元素和将连接信息放入
的概念是相互排斥的

JPA提供者可以创建和管理连接(使用属性),也可以从容器中获取连接(使用jta数据源)。把两者都放进去会给你带来不可预知的结果。如果JPA提供商选择遵守连接属性,您可以非常轻松地关闭事务管理、连接池等

您想要的是在容器中配置所有这些内容,而不要在持久性单元声明中进行任何配置

更新
TransactionManagementType.BEAN
(BMT)和
UserTransaction
的组合应该可以。请注意,您希望捕获可丢弃的
而不是
异常
。此外,
rollback()
调用还可以抛出应该处理的异常。不过,总的来说,这应该会产生您想要的结果

请仔细注意,虽然这看起来与您从
TransactionManagementType.CONTAINER
(CMT)中获得的几乎相同,但没有拦截器,但它们在一个关键方面存在差异:

  • 两个CMT bean可以共享同一事务
  • 两个BMT bean不能共享同一事务
这是因为在使用BMT调用任何bean之前,容器需要挂起任何可能正在进行的事务。在这方面,术语Bean管理的事务实际上有点用词不当,因为容器在调用bmtbean之前总是对任何正在进行的事务采取行动


因此,BMT和CMT不是平等的,实际上不可能使用BMT实现一些基本的CMT功能,例如
支持
必需的

感谢您的重播!我已经从persistence.xml中删除了所有属性(除了),感谢您的重播!我认为,这是一个很好的观察。但这并没有解决我的问题。可能问题与TransactionManagementType有关(它应该使用TransactionManagementType.CONTAINER,但在本例中我得到了异常:“java.lang.IllegalStateException:线程上的tx错误:预期TransactionImple”)
@Transactional
@Interceptor
public class TransactionInterceptor implements Serializable {


    @Resource
    private UserTransaction userTransaction;

    @AroundInvoke
    public Object verifyAccess(InvocationContext context) throws
            Exception {
        Object result = null;

        try {
            userTransaction.begin();
            result = context.proceed();
            userTransaction.commit();
        } catch (Exception e) {
                userTransaction.rollback();
             throw new CustomRuntimeException(e.getMessage());
        }

        return result;
    }

}
<property name="hibernate.connection.autocommit" value="true"/>