728x90
반응형
MySql 에서는 레코드에 락을 걸 수 있다. 이것을 X락, Exclusize Lock, 쓰기락 이라고 한다.
트랜잭션이 끝날 때 까지 읽기, 또는 쓰기를 실행 할 수 없다.
X락은 중첩해서 걸 수 없다. 앞 트랜잭션이 끝날 때 까지 대기해야한다.
트랜잭션이 커밋 되는 순간 락이 해제된다.
public interface CouponJpaRepository extends JpaRepository<Coupon, Long> {
@Lock(LockModeType.PESSIMISTIC_READ)
@Query("SELECT c FROM Coupon c WHERE c.id = :id")
Optional<Coupon> findCouponWithLock(Long id);
}
JpaRepository 에 락을 적용시켜준다.
public class CouponIssueService {
@Transactional
public void issue(long couponId, long userId) {
Coupon coupon = findCouponWithLock(couponId);
coupon.issue();
saveCouponIssue(couponId, userId);
}
@Transactional(readOnly = true)
public Coupon findCouponWithLock(long couponId) {
return couponJpaRepository.findCouponWithLock(couponId).orElseThrow(() -> {
throw new CouponIssueException(COUPON_NOT_EXIST,
"쿠폰 정책이 존재 하지 않는다. %s".formatted(couponId));
});
}
service 로직에 적용 시킨다.
public class CouponIssueRequestService {
private final CouponIssueService couponIssueService;
private final DistributeLockExecutor distributeLockExecutor;
public void issueRequestV1(CouponIssueRequestDto requestDto) {
couponIssueService.issue(requestDto.couponId(), requestDto.userId());
log.info("쿠폰 발급 완료. couponId: {}, userId: {}", requestDto.couponId(), requestDto.userId());
}
}
레디스 락을 해제시켜준다.
테스트 진행:
redis 를 활용할 때보다 RPS 가 향상 되었다.
테스트 결과
coupon 발급이 300개가 되었고
coupon_issue table에 레코드가 300개 들어갔다.
728x90
'JAVA > 프로젝트' 카테고리의 다른 글
쿠폰 선착순 발급 이벤트 - redis 분산락 쿠폰 발급 문제점. (0) | 2024.12.05 |
---|---|
쿠폰 선착순 발급 이벤트 - 쿠폰 발급 서버 구조 학습, 적절한 redis 데이터 구조 결정. (3) | 2024.12.02 |
쿠폰 선착순 발급 이벤트 - 동시성 이슈 해결 synchronized (1) | 2024.11.30 |
쿠폰 선착순 발급 이벤트 - locust 설정, docker-compose.yml 작성 (0) | 2024.11.28 |
쿠폰 선착순 발급 이벤트 - MySql, Docker 설정, 포트 충돌 해결. (0) | 2024.11.28 |