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: Tomcat 8 にデプロイする必要があるため、@Transactional の使用はオプションではありません。

4

1 に答える 1

2

私見あなたが求めていることは意味がありません。JAX-RS ライブラリは、インターセプターを介して例外マッピングを実装する必要がないためです。

ただしTransactionRequiredInterceptor、ブロックを使用して例外に応答することはできます。これはfinally、JVM が常に (ほぼ) その実行を保証しているためです。

とにかく、それが良い考えかどうかは疑わしい

まず、はるかに良い方法は、追加のレイヤー (serviceまたはと呼びましょうdao) を持ち、そのようなクラス メソッドをインターセプトすることです。

次に、トランザクション管理の実装に大量のバグがあることを 100% 確信できます。あなたの場合(CDIとTomcat)の私見では、DeltaSpikeが最善の方法です。これは、すでにそのような@Transactionalインターセプターを提供しているためですorg.apache.deltaspike.jpa.api.transaction.Transactional。私は個人的にそれを使って大成功を収めています。

ところで: 他にも多くの便利な機能があるため、Apache DeltaSpike も試すことができます。

于 2015-11-28T15:19:11.117 に答える