멘토링을 진행하면서, 낙관적락 사용과 비관적락 사용에 대해 정확히 인지하지 못하는 주니어 개발자들이 많다는 것을 느꼈다.
val Object = 오늘은 왜 충돌이 많이 발생하는 상황에서 비관적락이 낙관적락보다 더 처리속도가 빠른지를 포스팅 하려고 한다.
1. 비관적락에서의 대기시간
: 비관적 락(Pessimistic Lock)에서 최초 락을 획득하고 이후 트랜젝션이 락을 점유하려고 요청 시 이전 락이 해제될 때까지 다음 트랜잭션은 DB 레벨에서 대기하게 된다.
2. 비관적 락과 락 관리 순서
- 비관적 락은 주로 SELECT ... FOR UPDATE 같은 쿼리에서 사용되며, 해당 데이터에 대한 락을 DB 레벨에서 걸고 관리한다.
- 트랜잭션이 완료되어 커밋(commit) 또는 롤백(rollback)이 수행될 때 락이 해제
- 다른 트랜잭션은 이 락이 해제될 때까지 DB에서 대기 상태로 됨
3. 그럼 이때 대기 처리는 어디에서 이루어지는가?
DBMS가 대기 처리를 수행합니다.
- 락이 걸린 리소스에 대해 요청이 들어오면, DBMS는 요청을 대기 큐에 추가하고, 락이 해제되면 순차적으로 처리한다.
- 대기 중인 트랜잭션은 CPU를 소비하지 않고, DBMS 내부에서 관리된다.
4. 웹서버(WAS)와의 상호작용
웹서버나 WAS는 락 상태를 알지 못한다.
: 클라이언트가 요청을 보내면, 해당 요청은 DBMS로 전달되고, DBMS에서 처리 완료 후 응답을 반환한다. 만약 DBMS에서 락 때문에 대기 중이라면, 웹서버는 DBMS의 응답을 기다리는 상태가 되며, 이 경우 대기 시간은 웹서버나 WAS가 아닌 DBMS의 락 대기 시간이다.
5. 로직 구성은?
: 만약 락 대기가 길어지면, 웹서버의 요청 처리 시간이 길어지고, 타임아웃이 발생할 수 있다. 이 때문에 비관적 락은 주로 짧은 트랜잭션에서만 사용되며, 락 대기 시간을 최소화하도록 설계해야 한다.
그렇기 때문에 @Transactional 의 사용을 최소화할 수 있는 메쏘드단으로 낮추어 사용해야 한다.