흔히 DB에서 동시성 제어를 위해 사용하는 락에 대해서 다시 공부할 필요가 있어
정리하고 이해한다.
락은 말 그대로 잠금이다.
동시성 제어를 위해 사용되며 3가지 종류가 있다.
- 비관적 락(Pessimistic Lock)
- 낙관적 락(Optimistic Lock)
- 분산 락(Distrubuted Lock)
비관적 락
DB나 멀티 스레드 환경에서 여러 사용자가 동시에 동일 레코드에 접근할 때 충돌을 방지하기 위해
미리 락을 거는 방식으로, 사실상 의미그대로 잠금을 거는 것이다.
동시 접근이 많을 경우, 충돌이 많이 일어날 경우 사용한다.
비관적 락 종류
- Shared Lock(공유 락, S-Lock)
- 데이터 읽기 시 사용 하는 락
- 여러 트랜잭션이 동시 공유락 가능 (동시 읽기 허용)
- 배타 락이 걸리면 동시 접근 불가
- Exclusive Lock(배타 락, X-Lock)
- 데이터 쓰기시 사용하는 락
- 다른 어떤 트랜잭션도 접근 불가 (읽기도 불가)
- 락 건 트랜잭션만 읽기/쓰기 허용
사용법
SELECT ... FOR UPDATE; -- 배타 락
SELECT ... FOR SHARE; -- 공유 락
낙관적 락
동시 접근이 적고, 충돌이 적게 일어날 경우 사용
db 레코드에 별도의 version 컬럼을 두어
트랜잭션 시작 시점에서 읽어온 version과 업데이트 시점의 version을 비교하여
동시성을 제어한다.
락을 잡지 않으므로 성능 부담이 적으나
충돌시 예외가 발생하고 이는 애플리케이션 단에서 수동으로 재시도 혹은 롤백 처리를 해야한다.
동작원리
수정이 될 때마다 version이 1씩 상승
조회시 항상 version을 같이 가져오고
업데이트시 where로 조회한 version을 건다.
이때 다른 트랜잭션에서 바꿨다면 업데이트 쿼리 결과가 0건 반영으로 반환될 것이다.
이는 충돌 발생으로 판단되며, 애플리케이션 단에서 재시도 처리를 한다.
재시도 방법
다시 최신 version을 조회해서 업데이트 쿼리를 날린다.
사용법
//JPA
public class Entity {
//...
@Version
private int version;
}
//MyBatis
<update id="updateStock">
UPDATE product
SET stock = #{stock},
version = version + 1
WHERE id = #{id}
AND version = #{version}
</update>
분산 락
보통 여러 서버 즉, 분산 환경일때 사용하며
여러 서버가 동시에 같은 자원 접근을 막기 위해 사용한다.
종류
Redis의 (Lettuce)스핀락, redisson(pubSub)
myql의 네임드 락
Zookeeper
여기에 대해서는 필요할때 찾아서 구현해보는 걸로 한다.
'Back-End > DB' 카테고리의 다른 글
Real MySQL 8.0 [실행계획 : Extra 칼럼] (0) | 2025.09.03 |
---|---|
Real MySQL 8.0 [실행계획] (4) | 2025.09.01 |
정렬 방식 실렬 방식 실습 (0) | 2025.07.01 |
Real MySQL 8.0 [데이터 처리 방식 및 정렬] (0) | 2025.06.27 |
Real My Sql 8.0 [인덱스] (1) | 2025.06.20 |