<aside> 💡 고성능, 확장 가능, 스레드 안전한 레디스 자바 클라이언트
</aside>
sentx 메서드
를 통해 사용자가 직접 스핀락 형태를 구성Lettuce 전체 코드
Redis를 위한 implementation을 추가
//Redis
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
부모 트랜잭션과 자식 트랜잭션을 따로 작성한다.
//부모 트랜잭션
@Transactional
public void stockLock(String pgToken, Long memberId){
String redisLockKey = orderProductWithLettuceLock(pgToken, memberId);
redisRepository.unlock(redisLockKey);
}
//자식트랜잭션
@Transactional(propagation = Propagation.REQUIRES_NEW)
public String orderProductWithLettuceLock(String pgToken, Long memberId) {
' ' ' ' '
//Lettuce Lock
String redisLockKey = REDIS_LOCK_KEY_PREFIX + productId;
while (!redisRepository.lock(redisLockKey)) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
Product product = productRepository.findById(Long.valueOf(productId))
.orElseThrow(() -> new ProductNotFoundException(ErrorCode.PRODUCT_NOT_FOUND));
if (product.getStock() == 0) {
throw new ProductOutOfStockException(ErrorCode.PRODUCT_OUT_OF_STOCK);
}
// 결제 승인 요청 api
// kaKaoPaymentService.payInfo(pgToken, memberId, Long.valueOf(productId), tid);
product.saleProduct();
paymentHistoryRepository.save(paymentHistory);
return redisLockKey;
}
Product product = productRepository.findById(Long.valueOf(productId))
.orElseThrow(() -> new ProductNotFoundException(ErrorCode.PRODUCT_NOT_FOUND));
if (product.getStock() == 0) {
throw new ProductOutOfStockException(ErrorCode.PRODUCT_OUT_OF_STOCK);
}
서비스 코드에서 @Transactional 어노테이션을 붙이면, 기본적으로 propagation type이 REQUIRED이다.
현재 lettuce 서비스 코드에서는 부모트랜잭션이 REQUIRED
, 자식 트랜잭션이 REQUIRES_NEW
이다.