次のアプローチを使用してトランザクションを管理する 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 の使用はオプションではありません。