Как расставить приоритеты CDI Interceptor над JAX-RS ExceptionMapper
У меня есть веб-сервис REST, который управляет своими транзакциями, используя следующий подход:
@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.
1 ответ
ИМХО, что вы спрашиваете, не имеет смысла. Потому что ваша библиотека JAX-RS не должна реализовывать отображение исключений через перехватчики.
Но все же ваш TransactionRequiredInterceptor
может ответить на исключение, используя finally
блок - потому что JVM всегда (почти) гарантирует его выполнение.
В любом случае, я сомневаюсь, что это хорошая идея.
Во-первых, гораздо лучше было бы иметь дополнительный слой (назовем его service
или же dao
) и перехватывать такие методы класса.
Во-вторых, вы можете быть на 100% уверены, что ваша реализация управления транзакциями будет иметь множество ошибок. ИМХО в вашем случае (CDI и Tomcat) лучший путь - это DeltaSpike, потому что он уже дает вам такой @Transactional
перехватчик: org.apache.deltaspike.jpa.api.transaction.Transactional
, Я использую это лично с большим успехом.
Кстати: вы можете попробовать Apache DeltaSpike также благодаря множеству других полезных функций - они могут избавить вас от многих головных болей.