package com.softwaremill.common.cdi.transaction; import javax.annotation.Resource; import javax.interceptor.AroundInvoke; import javax.interceptor.Interceptor; import javax.interceptor.InvocationContext; import javax.transaction.Status; import javax.transaction.UserTransaction; import java.io.Serializable; /** * An interceptor for the {@link Transactional} annotation. * Must run before the {@link TransactionalInterceptor}. * Does not work if the tx is started before setting the timeout. * @author Adam Warski (adam at warski dot org) * @link http://smokeandice.blogspot.com/2009/12/cdi-and-declarative-transactions.html */ @TransactionTimeout(timeout = 5) @Interceptor public class TransactionTimeoutInterceptor implements Serializable { @Resource private UserTransaction utx; @AroundInvoke public Object intercept(InvocationContext ic) throws Throwable { // make sure the transaction is active if (utx.getStatus() != Status.STATUS_ACTIVE) { throw new RuntimeException("Transaction is not active and timeout cannot be set"); } // check type TransactionTimeout timeout = ic.getTarget().getClass().getAnnotation(TransactionTimeout.class); // if not available check method if (timeout == null) { timeout = ic.getMethod().getAnnotation(TransactionTimeout.class); } // set the timeout utx.setTransactionTimeout(timeout.timeout()); return ic.proceed(); } }