Skip to content

Instantly share code, notes, and snippets.

@LenKIM
Created May 13, 2025 07:03
Show Gist options
  • Save LenKIM/cfffa7d285cad78a4c9a481f097b3daa to your computer and use it in GitHub Desktop.
Save LenKIM/cfffa7d285cad78a4c9a481f097b3daa to your computer and use it in GitHub Desktop.
트랜잭션을 어떻게 강제로 먹이지 않을까?
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
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.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.TransactionSynchronizationManager;
@Slf4j
@Aspect
@Component
@RequiredArgsConstructor
@Order(Ordered.HIGHEST_PRECEDENCE)
public class DistributedLockAspect {
private final LockKeyGenerator generator;
private final LockStrategyRegistry registry;
private final PlatformTransactionManager transactionManager;
@Around("@annotation(kr.hhplus.be.ecommerce.support.lock.DistributedLock)")
public Object lock(ProceedingJoinPoint joinPoint) throws Throwable {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
DistributedLock lock = signature.getMethod().getAnnotation(DistributedLock.class);
if (lock.isTrans()) {
// ...
}
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setName(joinPoint.getThis().getClass().getName());
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus transaction = transactionManager.getTransaction(def);
String key = generator.generateKey(signature.getParameterNames(), joinPoint.getArgs(), lock.key(), lock.type());
LockTemplate template = registry.getLockTemplate(lock.strategy());
Object o = template.executeWithLock(key, lock.waitTime(), lock.leaseTime(), lock.timeUnit(), joinPoint::proceed);
transactionManager.commit(transaction);
return o;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment