Race Condition
race condition이란 여러 개의 프로세스가 공유 자원에 동시에 접근할 때 실행 순서에 따라 결과값이 달라질 수 있는 상태이다. 자료의 일관성을 해칠 수 있음으로 멀티 프로세스 환경에서는 경쟁 상태에 대한 대비가 필요하다.
발생하는 경우와 해결 방법
- 커널 코드 실행 중에 인터럽트가 발생할 경우 - 커털이 가진 전역 변수는 모든 프로세스의 공유물이므로 경쟁 상태의 가능성이 있다. 이 경우 커널 모드에서 작업을 수행하는 동안에는 인터럽트를 비활성화 시켜 인터럽트가 CPU 제어권을 가져가지 못하도록 하여 해결 할 수 있다.
- 프로세스가 시스템 콜을 하여 커널모드로 진입하여 작업을 수행하는 도중에 문맥 교환이 발생한 경우 - 프로세스A가 커널모드에서 데이터를 조작하던 중 시간이 초과되어 CPU제어권이 프로세스B로 넘어가 같은 데이터를 조작하는 경우 경쟁 상태가 발생한다. 이 때는 프로세스가 커널 모드에서 작업을 하는 경우에는 시간이 초과되더라도 CPU 제어권이 다른 프로세스에 넘어가지 않도록 한다.
- 멀티 프로세서에서 공유 메모리 내의 커널 데이터에 접근할 경우 - 커널 내부에 있는 각 공유 데이터에 접근할 때마다 그 데이터에 대해 lock/unlock함으로써 해결할 수 있다.
Synchronized 키워드 사용
Java는 Race Condition을 해결하기 위해 synchronized 키워드를 제공한다. synchronized 키워드가 붙은 메소드 블럭은 한 번에 하나의 스레드만 접근할 수 있도록 하여 Race Condition이 발생하지 않도록 한다. synchronized 키워드는 내부의 모든 동작에 대해 lock을 걸기 때문에 필요한 부분만 lock을 거는 다른 기법에 비해 성능상 오버헤드가 심하다는 평을 받기도 한다.
하지만 @Transactional 키워드가 붙은 메소드를 실행할 때는 해당되지 않는다. 선언전 트랜잭션 관리 방식의 경우 트랜잭션 프록시가 트랜잭션 처리 로직을 수행하고, 트랜잭션이 시작한 후에 실제 서비스를 호출한다. 이후 트랜잭션을 종료한다. 이 때 트랜잭션이 종료되기 전에 다른 쓰레드가 synchronized가 붙은 메소드에 접근하면 커밋되지 않은 데이터에 접근하는 것이 된다.
또한 서버가 여러대가 있는 경우에도 synchronized 키워드 사용만으로는 데이터 베이스의 정합성이 맞지 않는 문제를 해결할 수 없다.
Pessimistic Lock 의 사용
Pessimistic lock 이란 실제로 데이터에 lock을 걸어서 정합성을 맞추는 방법이다.
메서드 레벨에 @Transactional 및 DB조회 시에 @Lock(LockModeType.PESSIMISTIC_WRITE)을 사용하여 트랜잭션이 시작할 때 Shared/Exclusive Lock을 적용한다. Pessimistic lock은 동시성 충돌이 잦을 것으로 예쌍되어 동시성을 강력하게 지켜야 할 때 사용해야 한다. 왜냐하면 별도의 lock을 잡기 때문에 속도가 느리고 경우에 따라 dead lock 위험이 있기 때문이다.
음.. 이걸로 될까? 좀 더 파봐야겠음.... 역시 실제 써보지 못하니 잘 모르겠다. :(
'기타 CS' 카테고리의 다른 글
기술 면접 기출 - Java 예외(Exception) 처리 방법 (0) | 2023.03.01 |
---|---|
기술 면접 기출 - Spring Bean 객체의 생명주기 (0) | 2023.03.01 |
기술 면접 준비 - 기타 기출 질문들 (0) | 2023.02.27 |
기술 면접 준비 - RESTful API (0) | 2023.02.27 |
기술 면접 준비 - 필터(Filter) vs 인터셉터(Interceptor) (0) | 2023.02.27 |