0

我有一个 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 不是一个选项,因为我需要在Tomcat 8 上部署。

4

1 回答 1

2

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

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

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

首先,更好的方法是增加一层(我们称之为serviceor dao)并拦截此类方法。

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

顺便说一句:由于许多其他有用的功能,您也可以尝试 Apache DeltaSpike - 它们可以为您省去很多麻烦。

于 2015-11-28T15:19:11.117 回答