[최종 프로젝트 - 현재 시세를 반영한 모의 투자 서비스] 주문 도메인 성능 개선(Redisson 분산락 적용)

2025. 6. 18. 14:00·프로젝트/프로젝트 회고

이번 프로젝트에서 모의 투자 서비스의 핵심 기능인 "주문 체결"에 대해 맡았다.

실시간 시세를 기반으로 여러 사용자가 동시에 시장가 매수를 시도할 경우, 잔고 차감 및 보유 종목 업데이트가 정확히 반영되지 않으면 데이터 정합성 문제가 발생한다.

이 문제를 해결하기 위해, Redisson 기반의 분산락을 커스텀 어노테이션 방식으로 도입하였다. 

 

 

✅ TradeService에 Redisson 락 적용하기

📌 문제 상황

  • 다수의 유저가 동시에 동일한 계좌로 매수 주문을 보낼 경우, 잔고 차감 및 보유 종목 수량 증가가 동시성 문제가 발생하면서 데이터가 꼬여버렸다.

 

동시성 제어에 대해 이론적으로 다룬 글이 있어 해당 글을 참고하였다.

https://computerreport.tistory.com/154

 

[Spring]동시성 제어(Redisson)

5분 브리핑을 진행하면서 다수의 멀티 스레드로 동시 주문을 실행하면 데이터 정합성 문제가 발생하는 것을 다루었고 본격적으로 성능 개선을 위해 분산 락을 적용해볼려고한다.✅분산 환경에

computerreport.tistory.com

 

📌 해결 방법

  • Redisson을 활용한 분산락을 커스텀 어노테이션으로 구성하였다.
  • 또한 트랜잭션을 락 내부에 배치하여 커밋 후 락 해제되도록 구성하였다
@Around("@annotation(distributedLock)")
public Object lock(ProceedingJoinPoint joinPoint, DistributedLock distributedLock) throws Throwable {
    RLock lock = redissonClient.getLock(distributedLock.key());
    boolean isLocked = lock.tryLock(...);
    try {
        return transactionTemplate.execute(status -> joinPoint.proceed());
    } finally {
        if (isLocked && lock.isHeldByCurrentThread()) lock.unlock();
    }
}

 

 

❓ 그럼 주문 저장에도 락이 필요할까?

"주문 체결은 락이 필수지만, 그 이전 단계인 '주문 저장'에는 락이 꼭 필요할까?" 라는 생각이 들었다.

 

📌 전제 조건

  • 주문 저장 로직은 각 사용자의 고유한 계좌를 대상으로 처리된다.
  • 주식 종목에 대한 수량 한도 제한이 없으며, 동일 종목에 대한 중복 주문도 가능하다.
  • 주문 저장 단계에서는 단순히 DB에 주문 정보를 넣는 수준의 처리만 존재한다.

 

결론적으로 굳이 락을 걸 필요 없다.

 

 

이유는 체결은 공유자원을 변경하므로 락이 필요하지만 주문 저장은 개별 자원에 대한 독립 처리이므로 락이 없어도 정합성 유지가 가능하다. 또한 불필요한 락 처리는 성능 속도를 저하 시킬 수 있다.

 

 

 

❓사용자 요청 중복 이슈는 어떻게 처리해야 할까?

근데 디테일 하게 들어가면 또 다른 상황을 생각 해보아야한다.

웹 환경에서는 사용자 인터페이스(UI)나 네트워크 지연으로 인해 같은 주문 요청이 중복해서 서버로 전송될 수 있다.

예를 들어,

 

  • 사용자가 버튼을 한 번 클릭했지만, 브라우저에서 두 번 요청을 보내는 경우 (더블 클릭, UI 지연)
  • 네트워크 재전송으로 동일 요청이 반복될 가능성

 

이 경우에도 락을 걸어야 할까?

중복 요청 방지는 락보다 “중복 요청 방지 로직”으로 해결하는 것이 바람직하다.

  • 락은 자원 보호용이며, 같은 요청이 여러 번 오는 걸 감지하거나 방지하는 목적은 아니다.
  • 이것은 분산락의 책임 영역이 아니라, API 요청의 무결성 보장 책임에 가까운 것이다.

이 문제를 해결할려면 Redis에 3~5초 정도 저장해두고, 같은 내용이 오면 무시하는 방식을 생각 해봐야한다.

다음글은 Redis 캐싱을 이용한 성능개선을 다뤄보려고 한다.

 

 

 

 

 

'프로젝트 > 프로젝트 회고' 카테고리의 다른 글

[최종 프로젝트 - 모의 투자 서비스] RabbitMQ 를 이용한 실시간 지정가 체결  (3) 2025.06.24
[최종 프로젝트 - 현재 시세를 반영한 모의 투자 서비스] 5분 브리핑  (2) 2025.06.10
[최종 프로젝트 - 현재 시세를 반영한 모의 투자 서비스] S.A 작성  (4) 2025.06.10
[팀 프로젝트-쇼핑몰]성능 최적화 및 마무리  (0) 2025.05.26
[팀 프로젝트-쇼핑몰]S.A 작성  (1) 2025.05.16
'프로젝트/프로젝트 회고' 카테고리의 다른 글
  • [최종 프로젝트 - 모의 투자 서비스] RabbitMQ 를 이용한 실시간 지정가 체결
  • [최종 프로젝트 - 현재 시세를 반영한 모의 투자 서비스] 5분 브리핑
  • [최종 프로젝트 - 현재 시세를 반영한 모의 투자 서비스] S.A 작성
  • [팀 프로젝트-쇼핑몰]성능 최적화 및 마무리
코딩로봇
코딩로봇
금융 IT 개발자
  • 코딩로봇
    쟈니의 일지
    코딩로봇
  • 전체
    오늘
    어제
    • 분류 전체보기 (151) N
      • JavaScript (8)
      • SQL (11)
      • 코딩테스트 (30)
        • Java (15)
        • SQL (13)
      • Java (10)
      • 프로젝트 (30) N
        • 트러블슈팅 (10)
        • 프로젝트 회고 (18) N
      • git,Github (2)
      • TIL (38)
      • Spring (20)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    스파르타 코딩 #부트캠프 #첫ot
    java #arraylist #list #배열
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
코딩로봇
[최종 프로젝트 - 현재 시세를 반영한 모의 투자 서비스] 주문 도메인 성능 개선(Redisson 분산락 적용)
상단으로

티스토리툴바