如何将CDI拦截器优先于JAX-RS ExceptionMapper



我有一个REST Web服务,它使用以下方法管理其事务:

@Inherited
@InterceptorBinding
@Retention(RetentionPolicy.RUNTIME)
@Target({METHOD, TYPE, FIELD, PARAMETER})
public @interface TransactionRequired {
}
@Interceptor
@TransactionRequired
public class TransactionRequiredInterceptor {
    @Inject
    private EntityManager entityManager;
    @AroundInvoke
    public Object manageTransaction(InvocationContext ctx) {
        try { 
            ..start transaction..
        }
        catch(Exception e) { 
            ..rollback.. 
        }
    }
}

我也在映射我的例外情况,如下所示:

@Provider
public class RuntimeExceptionMapper implements ExceptionMapper<RuntimeException> {
    @Override
    public Response toResponse(RuntimeException exception) {
        .. return some response..
    }
}

问题是,比如说,当抛出RuntimeException时(在事务启动后),它会立即被RuntimeExceptionMapper截获,并且该事务永远不会回滚。

因此,我需要一种方法来对TransactionRequiredInterceptor进行优先级排序。。

Obs:使用@Transactional不是一个选项,因为我需要在Tomcat8上进行部署。

IMHO您的要求没有意义。因为您的JAX-RS库不必通过拦截器来实现异常映射。

但是TransactionRequiredInterceptor仍然可以通过使用finally块来响应异常,因为JVM总是(几乎)保证它的执行。

无论如何,我怀疑这是否是个好主意

首先,一个更好的方法是有额外的层(让我们称之为servicedao)并拦截这样的类方法。

其次,您可以100%确信您的事务管理实现将有过多的错误。IMHO在您的情况下(CDI和Tomcat),最好的方法是DeltaSpike,因为它已经为您提供了这样的@Transactional拦截器:org.apache.deltaspike.jpa.api.transaction.Transactional。我个人使用它取得了巨大成功。

顺便说一句:你可以试试Apache DeltaSpike,因为还有很多其他有用的功能——它们可以帮你省去很多麻烦。

最新更新