1일 1개념정리 24.08.09.금 ~
큰 결정에 큰 동기가 따르지 않을 때도 있다. 하지만 큰 결심이 따라야 이뤄낼 수 있다.
무조건 무조건 1일 1개의 개념 정리하기 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#66. DB Lock
오늘은 DB에서 말하는 Lock에 대해서 알아보자. 여기서 정리했던 것 처럼, 보통 OS에서 나오는 개념인데 오늘은 데이터베이스 입장에서 Lock을 어떻게 관리하는지 알아보자. 그리고 함께 자주 언급되는 "낙관적 락"과, "비관적 락"에 대해서 알아보자.
Lock
Lock은 데이터베이스에서 여러 트랜잭션이 동시에 동일한 데이터에 접근할 때 생기는 문제를 방지하기 위한 기술이다. Lock을 사용하면 하나의 트랜잭션이 작업할 때 다른 트랜잭션의 접근을 막을 수 있다. 앞서 이야기한 데드락과도 비슷한 맥락이 있는데, 오늘은 DB 관점에서 알아보자. DB에서 Lock은 테이블, 튜플 등에 대한 액세스를 제한하여 충돌을 방지하는 것을 말한다. 보통 다음과 같은 Lock이 있다.
- Shared Lock (S Lock) : Read에 대한 Lock이다. 여러 트랜잭션이 동시에 Shared Lock을 걸 수 있지만, 데이터를 수정하는 트랜잭션은 Shared Lock이 해제될 때까지 기다려야 한다. 읽는 도중에 값이 바뀌면 안되니깐 !!!
- Exclusive Lock (X Lock) : Update에 대한 Lock이다. Exclusive Lock이 걸리면 다른 트랜잭션은 해당 데이터에 접근할 수 없다.
- Optimistic Lock : 데이터 수정 시 충돌이 발생할 가능성이 낮다고 가정하고 Lock을 사용하지 않거나 최소한으로 사용하는 경우를 말한다. 데이터 수정 시점에 버전 번호나 타임스탬프를 비교해 충돌 여부를 확인한다.
- Pessimistic Lock : 데이터 수정 시 충돌이 발생할 가능성이 높다고 가정하고 Lock을 미리 설정해 다른 트랜잭션이 해당 데이터에 접근하지 못하도록 한다.
오늘은 이런 Lock 중에서, 낙관적 락과 비관적 락에 대해서 알아보자. 유튜브에도 관련 자료가 엄청 많고 ... 뭔가 이름도 재밌어서 정리해보고 싶었다 !!!!
Optimistic Lock
Optimistic Lock은 데이터의 충돌 가능성이 낮다고 가정하고, 별도의 Lock을 걸지 않고 작업을 진행한다. 그리고 데이터 갱신 시점에 충돌이 발생했는지 확인하고, 필요한 경우에만 충돌을 처리하는 방식이다. 한마디로 ... "에이 뭔 락이여 충돌 안나겄지 ~~" Optimistic Lock은 주로 데이터를 먼저 읽고 나중에 수정하는 경우가 많은 상황에서 유리하다.
충돌 확인은 레코드에 버전에 대한 번호나 TimeStamp를 통해 확인한다. 즉, 트랜잭션이 값 수정할 때 현재 버전과 수정 시점의 버전을 비교한다. 만약 버전이 서로 다르다면 ?? 트랜잭션이 실패하고, 예외가 발생한다.
- 장점 : Lock을 사용하지 않기 때문에 Lock 비용이 들지 않는다. 그리고 Lock 자체가 없으니깐 병목 현상이 적어 높은 동시성을 제공할 수 있다.
- 단점 : 만약 충돌이 발생하면 수정 작업을 다시 시도해야 하므로 재시도 로직이 필요하고, 충돌 가능성이 높은 상황에선 성능 저하가 발생한다.
EX) (내가 지어낸 흐름이므로 틀릴 수도 있음 .....) 내가 쇼핑몰에서 어떤 상품 구매하려 한다. "지금 1개 남았어요 !! 빨리 사세요 !!" 보고 내가 호다닥 사려고 한다. 읽기 시점에선 1개 남았다고 뜨고, 낙관적 락은 데이터 수정 시점에서 즉, 누군가 구매해서 수량이 줄어야 충돌을 확인하므로 내가 구매하려는 과정에서 이미 0으로 변경됐을 수 있다. 흐름을 정리해보자.
- 사용자 A와 B가 동시에 재고를 읽고, 서로 1개라고 표시됨.
- 사용자 A가 먼저 구매 요청을 보내고 재고를 0으로 업데이트함. 구매완료임. 이 과정에서 낙관적 락은 버전 번호를 비교하여 문제가 없음을 확인하고 업데이트를 성공시킨다.
- 사용자 B는 아직 1개인줄 알고 사려고 하는데, 실제 재고는 0이라고 충돌이 발생한다. 예외 처리로 넘어가고, 이미 결제된 상태에서 처리하느 로직이라면 환불된다.
* 추가) "버전 비교"가 뭔 소리냐면, A가 먼저 구매했고 이때 구매가 이루어지면서 재고 1에 버전1이었던 것이, 재고 0으로 바뀌면서 버전이 2로 바뀐다는 소리다. 근데 B가 구매하려고 봤더니 버전이 내껀 1이고, DB서버는 2네? 아 버전 안맞으니까 너 이거 못사 돌아가. 이렇게 된다. // 그리고 애당초 버전비교 자체가 Lock 안걸고 나중에 하려고 만드는 매커니즘이라 낙관적 락에서 사용되는 기술이고, 비관적 락에서는 Lock을 걸고 작업하니깐 굳이 버전 비교를 안해도 된다.
@Entity
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private int quantity;
@Version
private Long version; // 낙관적 Lock을 위한 버전 필드
}
Pessimistic Lock
비관적 락은 데이터의 충돌 가능성이 높다고 가정하고, 트랜잭션이 데이터에 접근할 때 다른 트랜잭션이 접근하지 못하게 Lock을 건다. Lock이 걸려있는 동안 다른 트랜잭션은 대기한다.
- 장점 : 충돌을 사전에 방지할 수 있어서 데이터 무결성을 확실히 보장한다.
- 단점 : Lock이 걸리면 다른 요청은 대기해야하니깐 성능 저하가 발생할 수 있고, DeadLock이 발생할 수 있다.
Ex) 비관적 락은 계좌이체같은 중요한 환경에서 유용하다. Lock이 없다면 어떻게 될까 ?? 내가 폰이랑 ATM에서 동시에 인출하려고 하는데 200만원에서 동시에 100만원씩 뺀다. Lock이 없으면 동시에 요청 처리되면서 200만원을 인출해도 잔액이 100만원으로 기록될 수 있다....
@Transactional
public Product findProductWithLock(Long productId) {
return entityManager.find(Product.class, productId, LockModeType.PESSIMISTIC_WRITE);
}
비교
낙관적 락 | 비관적 락 | |
Lock 전략 | Lock을 사용하지 않음, 갱신 시점에 충돌 검사 | 사전에 Lock을 걸어 다른 트랜잭션 차단 |
장점 | 높은 동시성, Lock 비용 없음 | 충돌 사전 방지, 데이터 무결성 보장 |
단점 | 충돌 발생 시 재시도 필요, 충돌 가능성 높으면 비효율적 | 성능 저하 가능성, Deadlock 발생 가능 |
사용 예시 | 데이터 변경이 자주 일어나지 않는 경우 | 충돌 가능성이 높은 경우, 중요한 데이터 보호 필요 |
'1일 1개념정리 (24년 8월~) > 데이터베이스' 카테고리의 다른 글
1일1개 (74) - 내 통장이 사실은 무한 ATM ? (0) | 2024.11.07 |
---|---|
1일1개 (58) - DB의 내용에 의한 참조 (0) | 2024.10.12 |
1일1개 (49) - 스키마랑 테이블 같은 거 아닌가요 ? (0) | 2024.10.03 |
1일1개 (43) - DB key (0) | 2024.09.27 |
1일1개 (41) - SQL 레퍼런스 (0) | 2024.09.23 |