어느 회사의 과제 코드리뷰 중 면접관으로부터 상황이 부여되어 해결책을 제시하라는 질문을 받았습니다.
문제사항
1. 두명의 사용자가 A라는 API를 동시에 호출할 경우가 발생할 수 있다.
2. A라는 API의 로직 중 데이터를 가져오는 SELECT 문까지 동시에 접근하였다.
3. 우연한 일치로 API 내에서 수정되어야 하는 데이터가 동일하다. 이럴경우 어떻게 해결하겠는가?
너무 많이 당황하고 해결책을 생각하지 못했다. 어떻게 이 문제를 해결해야 할지 생각해봤는데 간단히 해결할 수 있었다.
해결
1. SQL 변경
2. 정해진 횟수만큼 시도하여 모두 실패할 경우 예외발생
현재의 SQL문은 업데이트문으로써 업데이트문에 대한 조건만이 존재
업데이트문에 대한 조건을 상세히 하여 업데이트 셀렉트 구문으로 변경
수정된 UPDATE 문
<update id="modifyReceiver" parameterType="com.dto.Receiver$Info">
update tb_receiver set receiver_date = #{receiver_date}, user_id = #{user_id}, is_received = #{is_received}
where receiver_key = (select receiver_key from tb_receiver where is_received = '0' and receiver_key = #{receiver_key})
</update>
정해진 횟수(SELECT문을 통해 가져온 데이터의 개수)만큼 반복하여 업데이트하며 만약 업데이트를 할 수 없다면 예외를 발생시켰습니다.
수정된 코드
int retry = listNoReceived.size();
int result = 0;
int i = 0;
Receiver.Info receiver = null;
//멀티 스레드 환경에서 동시에 같은 데이터에 업데이트 할경우 대비
while(retry-- > 0) {
receiver = listNoReceived.get(i++);
receiver.setUser_id(userID);
receiver.setIs_received("1");
receiver.setReceiver_date(new Date());
result = receiverDao.modifyReceiver(receiver);
if(result > 0) break;
}
Optional.ofNullable(receiver).orElseThrow(()-> new CompletedSeedException("Exception"));
경험이 많았다면 면접에서 대답을 할 수 있었을텐데 아쉬었습니다. 좋은 경험을 했다고 생각하고 밑거름 삼아 정진해야겠습니다.
'Spring' 카테고리의 다른 글
Spring log4j 라이브러리란? (0) | 2021.03.25 |
---|---|
Springframework version 마이그레이션하는 방법 (0) | 2021.03.25 |
SELECT 문으로 데이터 랜덤으로 가져올 경우에 대한 성능 테스트 (0) | 2020.12.05 |
Mybatis에서 대량의 데이터를 넣을 때 bulk insert를 사용하자 (0) | 2020.12.05 |
@Service, @Controller, @Repository 과 @Component의 차이는? (0) | 2020.12.03 |