스프링 싱글톤 빈 상태 공유 이슈 정리

Heejun Kim·2025년 4월 20일

Spring

목록 보기
5/6

일단 대충 요약

  • 스프링 빈은 기본이 싱글톤임
  • 그런데 상태(state)를 필드에 저장하면... 멀티스레드 환경에서 데이터가 꼬인다
  • 특히 웹 요청은 대부분 동시성 환경 → 절대 상태 저장하지 말 것 ㅇㅋ?

👻 흔한 실수

@Component
public class TicketBookingService {

    private int seatCount;  // 🤡 상태 저장한 필드

    public void reserve(String user, int count) {
        this.seatCount = count;
    }

    public int getSeatCount() {
        return seatCount;
    }
}

이걸 두 명이 동시에 쓰면?

service1.reserve("UserA", 2);  // A: 2석 예약
service2.reserve("UserB", 5);  // B: 5석 예약

int seats = service1.getSeatCount();  // ❌ 기대: 2, 실제: 5

둘이 같은 인스턴스 공유하다 보니 B가 A꺼 덮어씀
상태 저장한 네가 범인이다


🛠️ 해결법: 상태 저장 금지, 리턴으로 끝내라

@Component
public class TicketBookingService {

    public int reserve(<String user, int count) {
        // 바로 리턴. 필드에 저장하지 않음
        return count;
    }
}

이건 동시 요청 100건 들어와도 안전함.
요청마다 데이터가 분리돼 있으니까.


😈 static 붙이면 더 심각해짐

public class TicketBookingService {
    private static int seatCount;  // 🚨 클래스 레벨 공유

    public void reserve(String user, int count) {
        seatCount = count;
    }
}

이건 인스턴스 상관없이 무조건 전역 공유됨.
심지어 테스트에서도 꼬일 수 있음.


🧠 실무 요약

설계 방식공유 위험설명
인스턴스 필드 (싱글톤)높음 ❌빈 하나니까 다 같이 씀
static 필드매우 높음 ⛔JVM 전체에서 공유
지역 변수없음 ✅요청마다 새로 생성
@RequestScope없음 ✅요청마다 빈 새로 만듦

✅ 결론

  • 싱글톤 빈은 무조건 무상태(stateless) 로 설계해야 안전
  • 상태 저장 = 동시성 터짐의 지름길
  • 진짜 필요한 경우엔 요청 스코프 쓰거나, 아예 DTO로 분리해라

0개의 댓글