동시성 제어에서 가장 중요한 출발점은 “여러 트랜잭션이 동시에 같은 데이터를 수정할 때 어떤 전략으로 충돌을 다룰 것인가”이다. 낙관적 락과 비관적 락은 이 질문에 대해 정반대의 철학을 가지고 있다.
낙관적 락은 충돌이 자주 일어나지 않을 것이라고 가정하며, 그래서 트랜잭션을 수행하는 동안 락을 선제적으로 잡지 않고 자유롭게 작업하게 둔다. 만약 충돌이 실제로 발생하면 그때 가서 감지하고, 충돌이 확인되면 롤백 후 재시도하는 방식이다.
반면 비관적 락은 충돌이 충분히 발생할 가능성이 있다고 판단하여, 아예 트랜잭션 시작 시점부터 또는 필요한 시점에 바로 락을 걸어 다른 트랜잭션의 접근을 차단한다. 즉, 낙관적 락은 ‘충돌 감지’, 비관적 락은 ‘충돌 회피’를 택한 방식이며, 두 전략의 근본 차이는 “언제 문제를 다룰 것인가”에 있다.
낙관적 락
비관적 락
낙관적 락은 충돌을 막지 않고 일단 자유롭게 처리하게 둔 뒤, 커밋 시점에 버전 비교를 통해 충돌 여부를 판단한다. 충돌이 발생하면 예외가 발생하고 해당 트랜잭션은 롤백된다. 이 과정에서 충돌을 해결하기 위해 재시도 전략이 필수이며, 충돌이 드문 환경에서는 부담이 적지만 충돌이 잦아지면 재시도 비용이 기하급수적으로 증가할 수 있다.
반면 비관적 락은 충돌 자체가 아예 발생하지 않도록 락을 사용해 경쟁을 차단한다. 한 트랜잭션이 락을 잡으면 다른 트랜잭션은 기다리거나 실패하므로, 충돌 시점을 애초에 예방하고 트랜잭션의 성공 여부를 예측 가능하게 만든다. 대신 락 경합이 심해지면 지연이나 데드락이 발생할 가능성이 커진다.