如何判断Java EE 6拦截器中的事务是否处于活动状态?

mar*_*cus 6 transactions java-ee interceptor

我打算为EJB编写拦截器,它基本上会做以下事情:

@AroundInvoke
public Object setContext(InvocationContext ctx) throws Exception {
    em.createQuery("... set something [database specific] ...").getSingleResult();
    try {
        return ctx.proceed();
    } finally {
        em.flush();
        em.createQuery("... unset something [database specific] ...").getSingleResult();
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是如果将em.flush()应用于使用@TransactionAttribute(NOT_SUPPORTED)或@TransactionAttribute(SUPPORTS)(即只读方法)注释的方法,则会抛出异常,而使用默认@的方法可以正常工作TransactionAttribute(REQUIRED)(即更改数据库的方法).

有没有办法判断一个事务是否处于活动状态,以避免在当前没有事务正在运行时调用em.flush(),或者我必须创建两个拦截器,一个是em.flush(),一个是没有它?

我无法注入UserTransaction,因为bean使用容器管理的事务.EntityManager的(em)事务方法仅适用于resource_local事务,而不适用于JTA事务.我需要em.flush()调用以确保unset查询是最后运行的东西.

作为奖金问题,有谁知道我想做什么是某种不良做法?我知道拦截器在与bean相同的上下文中运行,因此通过数据库会话分享内容是安全的,但我必须非常小心在退出时取消设置所有内容,因为连接是在容器中汇集的.

Avi*_*gal 13

您可以注入一个TransactionSynchronizationRegistry并使用getTransactionStatus来获取当前上下文中的事务状态,它返回一个intStatus类中的一个内容,在您要查找的情况下STATUS_NO_TRANSACTION

注入:

@Resource
TransactionSynchronizationRegistry tsr;
Run Code Online (Sandbox Code Playgroud)

检查交易状态:

if (Status.STATUS_NO_TRANSACTION == tsr.getTransactionStatus()) {
   // no transaction
}
Run Code Online (Sandbox Code Playgroud)