낙관적(Optimistic) 락과 비관적(Pessimisitc)락
두 락의 차이를 알아봅니다.
Goal
- 낙관적 락과 비관적 락에 대해서 알아봅니다.
- 비관적 락에 사용되는 공유락(Shared Lock) 과 베타락(Exclusive Lock)에 대해서 알아봅니다.
- 언제 어떤 락을 써야할지에 대해서 고민해봅니다.
비관적 락
자원 요청에 따른 동시성문제가 발생할것이라고 예상하고 락을 걸어버리는 방법론입니다.
- 트랜잭션의 충돌이 발생한다고 가정합니다.
- 하나의 트랜잭션이 자원에 접근시 락을 걸고, 다른 트랜잭션이 접근하지 못하게 합니다.
- 데이터베이스에서 Shared Lock(공유, 읽기 잠금) 이나 Exclusive Lock(배타, 쓰기 잠금) 을 겁니다.
- Shared Lock 의 경우, 다른 트랜잭션에서 읽기만 가능합니다. 또한 Exclusive lock 적용이 불가능합니다. (읽는동안 변경하는것을 막기 위해)
- Exclusive lock 의 경우. 다른 트랜잭션에서 읽기, 쓰기가 둘다 불가능합니다. 또한 Shared, Exclusive Lock 적용이 추가적으로 불가능합니다. (쓰는동안 읽거나, 다른 쓰기가 오는것을 막기위해)
1 |
|
장점
- 충돌이 자주 발생하는 환경에 대해서는 롤백의 횟수를 줄일 수 있으므로 성능에서 유리합니다.
- 데이터 무결성을 보장하는 수준이 매우 높습니다.
단점
- 데이터 자체에 락을 걸어버리므로 동시성이 떨어져 성능 손해를 많이 보게 됩니다. 특히 읽기가 많이 이루어지는 데이터베이스의 경우에는 손해가 더 두드러집니다.
- 서로 자원이 필요한 경우에, 락이 걸려있으므로 데드락이 일어날 가능성이 있습니다.
낙관적 락
자원에 락을 걸어서 선점하지말고, 동시성 문제가 발생하면 그때 가서 처리 하자는 방법론입니다.
- 트랜잭션의 충돌이 발생하지 않을것이라고 기대합니다.
- 일단 충돌이 나는것을 막지 않고, 충돌이 난것을 감지하면 그때 처리합니다.
- 일반적으로 version 의 상태를 보고 충돌을 확인하며, 충돌이 확인된경우 롤백을 진행시킵니다. (hashcode나 timestamp를 이용해서 충돌을 확인할 수 도 있습니다.)
- DB단에서 동시성을 처리하는것이 아닌, 어플리케이션단에서 처리 합니다.
1 |
|
- 이때 여러 작업이 묶인 트랜잭션으로 요청이 간 경우가 실패한경우, 개발자가 직접 롤백 처리 를 해주어야합니다.
장점
- 충돌이 안난다는 가정하에, 동시 요청에 대해서 처리 성능이 좋습니다.
단점
- 잦은 충돌이 일어나는경우 롤백처리에 대한 비용이 많이 들어 오히려 성능에서 손해를 볼 수 있습니다.
- 롤백 처리를 구현하는게 복잡할 수 있습니다.
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