동시성 상황(여러 사용자가 동시에 Stack 생성 요청)에서 중복 생성 문제를 확실히 막기 위해
@Lock(LockModeType.PESSIMISTIC_WRITE)를 이용해 락을 걸어주는 방식
비관적 락이란?
"다른 트랜잭션이 이 데이터를 수정할 수도 있다" 라고 비관적으로 예상하고,
아예 데이터를 읽을 때부터 락을 걸어서 다른 트랜잭션이 접근 못 하게 막는 것입니다.
즉, 데이터를 조회하는 순간부터 "이건 내 거야, 너 손대지 마" 하고 락을 걸어버리는 방식입니다.
동작 설명
1. 트랜잭션이 특정 데이터를 조회할 때, 데이터베이스에 락(Lock)을 건다.
2. 락이 걸린 데이터는 다른 트랜잭션이 수정하거나 삭제하려고 하면 대기하거나 에러가 발생한다.
3. 내 트랜잭션이 끝나기 전까지 다른 트랜잭션은 그 데이터를 변경할 수 없다.
비관적 락의 종류
종류 설명
PESSIMISTIC_READ 읽을 때 락을 걸지만 다른 트랜잭션도 읽기는 가능 (수정만 못함)
PESSIMISTIC_WRITE 읽을 때 락을 걸고, 다른 트랜잭션은 읽기, 쓰기 모두 막음 (완전 점유)
보통 쓰는 건 PESSIMISTIC_WRITE입니다. (쓰기 충돌 방지)
비관적 락을 써야 하는 상황
1. 데이터 충돌(중복 생성, 중복 수정)이 절대 발생하면 안 될 때
2. 동시에 여러 사용자가 특정 데이터를 조작할 가능성이 높을 때
ex) 상품 재고 차감, 회원 가입 시 유일한 닉네임 생성
비관적 락의 단점
락을 걸기 때문에 성능이 느려질 수 있습니다.
락을 오래 점유하면 Deadlock(교착 상태)이 발생할 수 있습니다.
락을 관리하는 부하가 DB에 추가됩니다.