본문 바로가기

Spring

멀티 스레드 환경에서 동일 데이터에 대해서 업데이트 시 고려해야 할 사항

어느 회사의 과제 코드리뷰 중 면접관으로부터 상황이 부여되어 해결책을 제시하라는 질문을 받았습니다.

 

문제사항

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"));

 

경험이 많았다면 면접에서 대답을 할 수 있었을텐데 아쉬었습니다. 좋은 경험을 했다고 생각하고 밑거름 삼아 정진해야겠습니다.