: 백엔드 처리를 하다보면 동시성은 당연히 고려해서 개발해야한다. 복기 겸 기록한다.
동시성을 제어하는 것을 백엔드가 필수적으로 고려해야하는 몫이다. 같은 자원에 대해 동일시간에 요청이 온다면 어떻게 처리해야할까? 물론 도메인의 성격에 따라 어떻게 처리할지는 다르지만 락에 대해 정리해 볼 필요가 있다.
일단 크게, DB수준의 락
과 어플리케이션 단의 락
이 있다.
이 둘은 모두 동시성 제어를 위해서 존재하지만, 구현방식이 다르다.
DB 락
- DB 엔진에서 관리하는 락
- DB 엔진이 자동으로 관리한다. → 날아가는 쿼리에 따라서 알아서 DB 락을 잡는다.
- 종류
- 행 락, 테이블 락, 페이지 락, 공유 락 … (필요할때 찾아보기)
어플리케이션 단의 락
- 어플리케이션에서 락을 잡는다.
- 개발자가 개발하고 있는 프로젝트 단에서 락을 잡는다.
- 종류
- 낙관적 락, 비관적 락, 분산 락, 네임드 락
- → 이건 실제 내가 구현할 수 있는 락들이기 때문에 알아놔야 한다.
어플리케이션 단의 락
1) 낙관적 락
- 정의
에이~ 트랜잭션끼리 충돌날일 거의 없어~ 일단 락 잡지말아봐~
- DB 커밋할때 락 잡음
- DB의 로우를 기준으로 락을 잡는다.
- 구현
- jpa에서 구현을 도와준다. version으로 관리 →
@version
어노테이션 지원
- jpa에서 구현을 도와준다. version으로 관리 →
2) 비관적 락
트랜잭션끼리 충돌날 확률? 무조건임. 일단 락부터 잡고 보자.
- DB 조회때부터 락을 잡음
LockModeType.*PESSIMISTIC_WRITE
→ 보통 이거 많이 사용함*- select … for update , 읽으면서 락 잡음 → 그 로우가 커밋되어야 접근이 가능함
- DB의 로우를 기준으로 락을 잡는다.
왜 명칭을 낙관적 락과 비관적 락이라고 지었는지.. 맨날 헷갈렸는데 이제는 완벽이해했다..
3) 분산락
: 멀티 서버 환경에서 잡는다.
- 주로 레디스를 사용해서 구현한다.
- 락에 대한 정보를 어딘가에 저장하고 있어야 한다.
- 여러대의 서버가 하나의 레디스를 바라보고, 그걸로 락을 잡는다.
4) 네임드락
: 특정이름을 기준으로 락을 잡는다.
- 락을 해제해주는 작업이 필요함
근데 잠깐… @Transactional
로도 락을 걸 수 있는데? 이건 어떤 종류의 락이지?
@Transactional
은 어플리케이션 단에서 구현하기 때문에 어플리케이션 단이라 생각할 수 있지만, 정답은 DB 수준의 락이다. 해당 락은 어플리케이션 단에서 걸지만 실제로는 DB에서 트랜잭션이 실행될때 락이 걸리기때문에 DB 수준의 락으로 분류한다.
🤨 잠깐의 회고
공부하면서 항상 헷갈렸던건
“정의”와 “구현”에 대해 구분하지 못하고 동일시 하다보니까 헷갈리는게 있었다.
위에서도 Lock의 정의와 그걸 구현한 방법들이 존재하는건데, 항상 같이 나오다보니 그 둘을 동일시하여 정의에 대한 이해보다는 구현하는 방법에만 매몰되어있던거 같다. 그래서.. 실질적으로는 해당 개념을 설명을 못하는….
무언가를 공부할때는 잘 나눠서 공부해야한다.
카테고리화 해서 정확히 무엇인지 이해하고 방법에 대해 알아봐야겠다.
정의 ≠ 구현법