스프링 동시성 문제
Spring ·동시성 문제란?
- 하나의 인스턴스에 여러 쓰레드가 동시에 접근하여 발생하는 문제.
- 동시성 문제는 트래픽이 적은 상황에서는 확률상 잘 나타나지 않고,
트래픽이 점점 많아질수록 자주 발생함. - 특히 스프링은 싱글톤으로 빈을 관리하기 때문에 동시성 문제에 조심 해야함.
- 이것을 해결하기 위한 방안 중 하나로 쓰레드 로컬이 있음.
쓰레드 로컬이란?
- 해당 쓰레드만 접근할 수 있는 특별한 저장소.
- 각 쓰레드마다 별도의 내부 저장소 제공.
- 같은 인스턴스의 쓰레드 로컬 필드에 접근해도 문제 없음.
- 자바는 언어차원에서 쓰레드 로컬을 지원하기 위한
java.lang.ThreadLocal 클래스 제공
쓰레드 로컬 사용법
- 값 저장 : ThreadLocal.set(xxx)
- 값 조회 : ThreadLocal.get()
- 값 제거 : ThreadLocal.remove()
- 예시
//선언 private ThreadLocal<String> str = new ThreadLocal<>(); //값 저장 str.set("abc"); //값 조회 str.get(); //값 제거 str.remove();
쓰레드 로컬 주의사항
- 해당 쓰레드가 쓰레드 로컬을 모두 사용하고 나면
쓰레드 로컬에 저장된 값을 제거해야 함. - 쓰레드 로컬의 값을 사용 후 제거하지 않고 그냥 두면 WAS(톰캣)처럼
쓰레드 풀을 사용하는 경우에 심각한 문제가 발생할 수 있음. - 사용자A 저장 요청
- 사용자A 저장 요청 종료
- 사용자B 조회 요청
- 사용자A를 저장하고 요청을 종료할 때, 쓰레드 로컬의 저장된 값을 지우지 않으면,
사용자B가 조회할 때, 사용자A가 사용했던 같은 쓰레드를 사용하게 된다면,
사용자A를 조회하게 된다.