@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건 들어와도 안전함.
요청마다 데이터가 분리돼 있으니까.
public class TicketBookingService {
private static int seatCount; // 🚨 클래스 레벨 공유
public void reserve(String user, int count) {
seatCount = count;
}
}
이건 인스턴스 상관없이 무조건 전역 공유됨.
심지어 테스트에서도 꼬일 수 있음.
| 설계 방식 | 공유 위험 | 설명 |
|---|---|---|
| 인스턴스 필드 (싱글톤) | 높음 ❌ | 빈 하나니까 다 같이 씀 |
| static 필드 | 매우 높음 ⛔ | JVM 전체에서 공유 |
| 지역 변수 | 없음 ✅ | 요청마다 새로 생성 |
@RequestScope | 없음 ✅ | 요청마다 빈 새로 만듦 |