본문 바로가기
Computer Engineering

주문 동시성 이슈 정리

by ybs 2022. 11. 14.
반응형

상황 설명

주문서 서버는 이벤트 기반으로 동작한다. 주문서를 만들고 결제 프로세스를 진행하면 '주문 완료 이벤트'를 발행한다. 그러면 해당 이벤트를 consume 해서 아래 그림 1번 작업이 수행된다. 문제는 1번 작업에서 API 를 호출해, 주문/결제 서버로 요청을 보냈는데 Read Timeout 에러가 발생했다. 

 

2번 주문 완료 요청중 에러가 발생하면 주문 실패 이벤트가 발행되고, consumer 가 4번 작업을 수행하면서 새롭게 API 를 호출한다. 여기서 기존 2번 작업과 동시성 이슈가 발생하면서 실제로는 주문이 완료 처리 됐지만 완료 되지 않았다는 결과를 받게 된다. 그래서 주문서 서버는 주문이 이미 완료 됐는지 확인하는 방어로직이 있음에도 불구하고 롤백 프로세스가 진행됐다.

 

 

주문서 서버 입장에서는 롤백이 진행 됐지만 실제로는 주문이 완료 처리 됐기 '주문 완료 이벤트' 를 새롭게 발행했고 그 이벤트를 consume 하는 서버들은 앞뒤가 안맞는 상황이 발생했다.

 

 

 

동시성 이슈 원인

1번 주문 완료 요청이 오면 작업을 수행하면서 db 조회 하는데, lock 을 잡고 시작한다. 그리고 2번 작업을 수행하던 중 read timeout 이 발생해 3번 요청이 오면서 4번 작업이 시작됐다. 하지만 2번에서 아직 주문 데이터를 insert 하기 전이라 4번에서 조회 결과가 안나왔다. 그래서 5번 임시 주문 데이터를 조회하는데 2번에서 잡은 lock 이 해제되기 전이라 대기를 한다. 하지만 6번에서 주문 데이터 생성이 완료 되고 임시 주문 데이터를 삭제하기 때문에 7번에서 lock 을 획득하고 임시 주문 데이터를 조회했지만 결과는 없게 된다. 그래서 주문이 완료되지 않았다고 판단하게 됐다.

문제 해결 방법

위에선 주문 데이터를 먼저 조회하고 임시 주문 데이터를 조회했는데, 그 순서를 바꿨다. 4번에서 임시 주문 데이터를 조회하면서 lock 을 획득할때까지 기다린다(1,2,3번은 기존과 동일). 5번이 완료되야 6번이 실행되기 때문에 주문 데이터는 항상 조회를 성공하고, 주문이 완료 됐다고 판단한다. 그리고 3번 요청이 주문이 완료됐다는 응답을 받으면, 주문서 서버는 방어로직에 따라 롤백하지 않고 주문 완료처리를 진행한다.

반응형