package kr.wisestone.owl.config.persistence.aop; import java.lang.reflect.Method; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.core.NamedThreadLocal; import org.springframework.core.Ordered; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.interceptor.TransactionAttributeSource; @Aspect public class TransactionDefinitionInterceptor implements Ordered { private static final ThreadLocal transactionDefinitionHolder = new NamedThreadLocal<>("Current aspect-driven transaction definition"); public static TransactionDefinition currentTransactionDefinition() { return transactionDefinitionHolder.get(); } public static boolean isCurrentTransactionReadOnly() { return transactionDefinitionHolder.get() != null ? transactionDefinitionHolder.get().isReadOnly() : false; } private final TransactionAttributeSource transactionAttributeSource; private int order = Ordered.LOWEST_PRECEDENCE - 10; public TransactionDefinitionInterceptor( TransactionAttributeSource transactionAttributeSource) { this.transactionAttributeSource = transactionAttributeSource; } @Around("@annotation(transactional)") public Object rememberTransactionDefinition( ProceedingJoinPoint joinPoint, Transactional transactional) throws Throwable { Method method = ((MethodSignature) joinPoint.getSignature()).getMethod(); Class targetClass = joinPoint.getTarget().getClass(); TransactionDefinition transactionDefinition = transactionAttributeSource.getTransactionAttribute(method, targetClass); boolean restore = false; if (transactionDefinitionHolder.get() == null) { transactionDefinitionHolder.set(transactionDefinition); restore = true; } try { return joinPoint.proceed(); } finally { if (restore) { transactionDefinitionHolder.set(null); } } } public void setOrder(int order) { this.order = order; } @Override public int getOrder() { return order; } }