티스토리 뷰

작업내용

매일 한정된 수의 사용자를 접속시점 무작위로 당첨시켜 사용자 정보를 적재 및 즉석으로 확인 가능한 기능

 

현재 상황

작업환경

  • 2대 이상의 다중 서버 환경
  • messageQueue 용도 서버 도입 불가
  • oracle DB RAC 환경

최초로직

쿠폰을 지급하기 전 현재까지 당첨된 사용자의 수를 조회하여 한정된 수치에 도달하지 않은 경우 당첨자 정보를 DB에 적재하는 방법

 

최초로직 문제점

예를들어 100개 한정된 수량의 쿠폰을 지급 시 다중서버 및 동시응모에 의한 100명을 초과하는 당첨자가 발생하는 경우를 확인
(이때 테스트는 junit을 통하여 멀티스레드 환경으로 진행)

 

최초로직 원인

A트랜잭션과 B트랜잭션이 거의 동시에 진행된 경우
A트랜잭션 조회 시점에 당첨자 수 99명
	당첨자 적재 100명
	커밋
B트랜잭션 조회 시점에 당첨자 수 99명
	당첨자 적재 101명
	커밋

만약 서버 수와 동시진행 숫자에 따라서 초과한 숫자는 더 커질 수 있다.

 

최초로직 개선

가능한 비즈니스 로직으로 풀어보려 당첨자 적재 후 일일 한정된 수치를 초과한 경우 해당 당첨자를 낙첨으로 업데이트하려고 하였으나 이 방법 역시 동일한 원인으로 동일한 문제점이 발생하였다.


개선로직 1

당첨자 적재하는 메서드에 @Transactional 격리레벨을 변경하는 방법

 

개선로직 1.1

적재 메서드에 @Transactional(isolation=Isolation.READ_UNCOMMITTED) 격리레벨을 적용하여 적재시점에 커밋되지 않은 내용까지 조회 후 한정 수치 초과 여부를 판단 후 당첨자 적재하는 방법

 

org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is java.sql.SQLException:
READ_COMMITTED와 SERIALIZABLE만이 적합한 트랜잭션 레벨입니다

오라클 DB는 해당 격리레벨을 지원하지 않기 때문이다.

 

개선로직 1.2

적재 메서드에 @Transactional(isolation=Isolation.SERIALIZABLE) 격리레벨을 적용하여 현재 총 당첨자 수를 저장하는 레코드를 동시에 수정할 수 없도록 하는 방법

해당 격리레벨을 적용하였을 때 테스트 환경임에도 성능이 감소되어 운영환경에 적용 시 성능저하 및 장애발생 우려되어 보류.

 

 


개선로직 2(성공)

oracle 시퀀스를 활용하여 당첨일련번호 발급하는 방법

DB서버가 1대 이상인 RAC환경이지만 시퀀스 옵션을 조정하여 WAS서버의 대수와 동시응모와 상관없이 시퀀스를 순차적으로 증가할 수 있도록 하는 방법

 

당첨자일련번호 용도의 오라클 시퀀스를 생성

CREATE SEQUENCE 당첨일련번호_시퀀스
  START WITH 1
  MAXVALUE 999999
  MINVALUE 0
  NOCYCLE
  NOCACHE
  ORDER;

NOCACHE와 ORDER 옵션을 선언하여 어떤 DB서버가 여러 대인 경우에도 일련번호를 순차적으로 발급받을 수 있다.

 

시퀀스를 활용하여 작성한 주요 로직은 아래와 같다.

if(당첨자인 경우){
	int 당첨자일련번호 = 적재하기 전 시퀀스를 통하여 당첨자일련번호 채번;
    
    if(당첨자일련번호 > 일일 당첨자한정수치){
        당첨되었지만 동시응모 후순위 상황으로 낙첨 처리
    } else {
        당첨정보와 함께 당첨자일련번호 적재
    }
}

 

오라클 시퀀스를 활용하여 동시성 문제는 해결하였으나 당첨인원의 수를 대량으로 늘리거나

로직상 시퀀스 증가를 계속해서 하는 경우라면 DB에도 부하가 발생할 수 있으나 현재 상황에서

작업 공수를 최소화 한 방법이다.

 

추후 messageQueue를 사용하여 동시성 문제를 해결하는 로직을 개인 프로젝트에 적용을 고려해보려 한다.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
글 보관함