package com.softwaremill.common.cdi.transaction; import org.slf4j.Logger; import javax.annotation.Resource; import javax.inject.Inject; 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 com.softwaremill.common.cdi.transaction.Transactional} annotation. * * @author Adam Warski (adam at warski dot org) * @link http://smokeandice.blogspot.com/2009/12/cdi-and-declarative-transactions.html */ @Transactional @Interceptor public class TransactionalInterceptor implements Serializable { @Inject private Logger logger; @Resource private UserTransaction utx; @AroundInvoke public Object intercept(InvocationContext ic) throws Throwable { boolean startedTransaction = false; if (utx.getStatus() != Status.STATUS_ACTIVE) { logger.debug("Starting a new transaction!"); utx.begin(); startedTransaction = true; } Object ret; try { ret = ic.proceed(); if (startedTransaction) { logger.debug("Transaction was executed properly!"); utx.commit(); } } catch (Throwable t) { if (utx.getStatus() == Status.STATUS_ACTIVE || utx.getStatus() == Status.STATUS_MARKED_ROLLBACK) { logger.debug("Rolling back transaction!"); utx.rollback(); } throw t; } return ret; } }