낙관적(Optimistic) 락과 비관적(Pessimisitc)락
낙관적(Optimistic) 락과 비관적(Pessimisitc)락
두 락의 차이를 알아봅니다.
Goal
낙관적 락과 비관적 락에 대해서 알아봅니다.
비관적 락에 사용되는 공유락(Shared Lock) 과 베타락(Exclusive Lock)에 대해서 알아봅니다.
언제 어떤 락을 써야할지에 대해서 고민해봅니다.
비관적 락
자원 요청에 따른 동시성문제가 발생할것이라고 예상하고 락을 걸어버리는 방법론입니다.
트랜잭션의 충돌이 발생한다고 가정합니다.
하나의 트랜잭션이 자원에 접근시 락을 걸고, 다른 트랜잭션이 접근하지 못하게 합니다.
데이터베이스에서 Shared Lock(공유, 읽기 잠금) 이나 Exclusive Lock(배타, 쓰기 잠금) 을 겁니다.
Shared Lock 의 경우, 다른 트랜잭션에서 읽기만 가능합니다. 또한 Exclusive lock 적용이 불가능합니다. (읽는동안 변경하는것을 막기 위해)
Exclusive lock 의 경우. 다른 트랜잭션에서 읽기, 쓰기가 둘다 불가능합니다. 또한 Shared, Exclusive Lock 적용이 추가적으로 불가능합니다. (쓰는동안 읽거나, 다른 쓰기가 오는것을 막기위해)
장점
충돌이 자주 발생하는 환경에 대해서는 롤백의 횟수를 줄일 수 있으므로 성능에서 유리합니다.
데이터 무결성을 보장하는 수준이 매우 높습니다.
단점
데이터 자체에 락을 걸어버리므로 동시성이 떨어져 성능 손해를 많이 보게 됩니다. 특히 읽기가 많이 이루어지는 데이터베이스의 경우에는 손해가 더 두드러집니다.
서로 자원이 필요한 경우에, 락이 걸려있으므로 데드락이 일어날 가능성이 있습니다.
낙관적 락
자원에 락을 걸어서 선점하지말고, 동시성 문제가 발생하면 그때 가서 처리 하자는 방법론입니다.
트랜잭션의 충돌이 발생하지 않을것이라고 기대합니다.
일단 충돌이 나는것을 막지 않고, 충돌이 난것을 감지하면 그때 처리합니다.
일반적으로 version 의 상태를 보고 충돌을 확인하며, 충돌이 확인된경우 롤백을 진행시킵니다. (hashcode나 timestamp를 이용해서 충돌을 확인할 수 도 있습니다.)
DB단에서 동시성을 처리하는것이 아닌, 어플리케이션단에서 처리 합니다.
이때 여러 작업이 묶인 트랜잭션으로 요청이 간 경우가 실패한경우, 개발자가 직접 롤백 처리 를 해주어야합니다.
장점
충돌이 안난다는 가정하에, 동시 요청에 대해서 처리 성능이 좋습니다.
단점
잦은 충돌이 일어나는경우 롤백처리에 대한 비용이 많이 들어 오히려 성능에서 손해를 볼 수 있습니다.
롤백 처리를 구현하는게 복잡할 수 있습니다.
Conclusion
비관적락 은 데이터의 무결성이 중요하고, 충돌이 많이 발생하여 잦은 롤백으로 인한 효율성 문제가 발생하는것이 예상되는 시나리오에서좋습니다.
낙관적락 은 실제로 데이터 충돌이 자주 일어나지 않을것이라고 예상되는 시나리오에서 좋습니다.
개인적인 생각으로는 데이터베이스 설계 단계에서 충돌여부가 발생하는지 어느정도 추측은 가능하나 확실치 않으므로, 애매한경우 비관적락 을 걸어두고 서비스 도중 실제로 충돌이 자주 일어나지 않는것이 확인 된 경우에 낙관적락 을 사용하는것이 좋지 않을까 생각합니다.
Reference
https://stackoverflow.com/questions/129329/optimistic-vs-pessimistic-locking
https://stackoverflow.com/questions/11837428/whats-the-difference-between-an-exclusive-lock-and-a-shared-lock
https://jeong-pro.tistory.com/94
https://sabarada.tistory.com/121
Last updated