본문 바로가기

개발기술/Spring

Spring 동시성이슈 해결

동시성이슈

여러 요청이 동일한 자원에 접근하며 발생하는 문제를 통칭함. 주로 DB에서 동일한 레코드를 동시접근하면 문제가 발생.

예) 사용자1과 사용자2가 계좌1의 잔액 1만원을 1천원 사용하는 요청을 동시에 보냈을때, 사용자1의 요청에 의해서 잔액이 9천원이 되기전에 사용자2의 요청이 시작되어 두 사용자의 요청 결과가 각각 잔액 9천원으로 저장되어 2천원 사용이 되어도 1천원만 감소하는 경우.

 

동시성이슈 해결방안

1. DB의존적인 해결방식 : DB 기기의 Isolation Level을 Serializable로 장치를 하거나 JPA의 Optimist Lock, Pessimistic Lock을 사용하여 DB의 기능을 사용

- 단점 : DB서버는 인프라 확장이 어려워 성능의 한계가 뚜렷한 기기이다. DB의존적인 방식은 DB에 많은 부담으로 성능이 낮고, 코드가  DB의 설정기능에 의존하여 개발자의 의도대로 코드동작의 자율성이 떨어짐.

 

2. 기타 인프라를 사용 : reddis의 경우 DB작업을 처리할때, single thread로 동작하고 메모리에 올려서 작업하기 때문에 성능적으로 좋은 편. 레디스에서 요청들에게 lock을 분배하는 방식.

 

3. 정책적 해결 : 우선 모든 사용자의 응답을 받고 즉시 처리하는 것이 아니라, 요청으로부터 시간 지연을 통해 요청을 순차적으로 처리하고] 처리를 해주는 방식. 예를 들어 선착순으로 처리하는 등의 정책을 설정하여 동시성을 관리하는 방식입니다. Kafka가 해당 방식에 사용됨.

 

캐쉬서버(Reddis)를 통한 Lock 분배

싱글스레드 메모리기반으로 비교적 적은 데이터로 빠르게 처리해야하는 데이터 처리에 적합함. 실무에서는 동시성을 제어하는 Lock 혹은 데이터 캐쉬에 사용된다.

 

 

 

reddis 사용목적

1. AOP를 활용한 SpinLock을 활용한 동시성 제어

SPINLOCk : 스레드가 Lock이 다른 스레드에게 점유되어있다고 실패처리하는 것이 아니라 여러번 Lock획득을 재시도하는 것을 spinlock이라고 함.

2. 데이터 캐슁을 통한 빠른 데이터 접근