I have a REST webservice that manage its transactions using the following approach:
@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..
}
}
}
And I am also mapping my exceptions like this:
@Provider
public class RuntimeExceptionMapper implements ExceptionMapper<RuntimeException> {
@Override
public Response toResponse(RuntimeException exception) {
.. return some response..
}
}
The issue is that when, lets say, an RuntimeException is thrown (after transaction being started), it is immediatelly intercepted by the RuntimeExceptionMapper and the transaction is never rollbacked.
Being so, I need a way to priorize the TransactionRequiredInterceptor..
Obs: Using @Transactional is not an option since I need to deploy on Tomcat 8.
IMHO what you are asking doesn't make sense. Because your JAX-RS library doesn't have to implement an exception mapping via interceptors.
But still your TransactionRequiredInterceptor
can respond to the exception by using a finally
block - because JVM always (almost) guarantee its execution.
Anyway, I doubt if it's a good idea.
Firstly, a much better way, would be to have additional layer (let's call it service
or dao
) and intercept such class methods.
Secondly, you can be 100% sure that your implementation of the transaction management will have plethora of bugs. IMHO in your case (CDI and Tomcat) the best way to go is DeltaSpike because it already gives you such @Transactional
interceptor: org.apache.deltaspike.jpa.api.transaction.Transactional
. I use it personally with a great success.
BTW: you can try Apache DeltaSpike also due to many other useful features - they can save you many headaches.