데이터베이스 - LOCK

락은  필요할까?

한정판으로 1개의 신발을 판매하고 있는데
두명의 사용자가 동시에 접근하게 된다면?
-> 커머스 서비스에서 이러한 일이 발생한다면 치명적
동시성 제어가 필요하다.
트랜잭션이 동시에 수행될때 일관성을 해치지 않도록 하는 DBMS의 기능

동시성제어는 어떻게 할까?
락으로 한다.
락에는 낙관적잠금, 비관적잠금

낙관적 잠금은 데이터 갱신  경합이 발생하지 않을 것이라고 보고
 사용자가 업데이트 완료하면, 동시 업데이트를 시도하는
다른 사용자들에게 충돌이 있음을 알리고 롤백시킨다.

A사용자 -> version read -> 구매완료 --> version update
B사용자 -> version read -> ........ -----> 구매완료 --> version update  충돌 발생 ---> rollback

비관적 잠금은 동일한 데이터를 동시에 수정할 가능성이 높다고 
다른 사용자는 먼저 시도한 사용자가 변경을 확인  레코드 잠금을 릴리스할때까지 대기해야 .

1. 데이터에 접근하기전 락을 걸어준다.
2. Read(count) 1
3. 구매완료
4. write(count) 0
5. UNLOCK
    과정이 있다.

다른 사용자는 대기한다.

낙관적 잠금은 동시 업데이트가 거의 없는 경우
비관적 잠금은 동시 업데이트가 빈번한 경우, 외부 시스템과 연동한 경우

비관적 잠금 연산의 종류

1. 공용락
- read 연산 실행 가능 , write 연산 실행 불가능
- 데이터에 대한 사용권을 여러 트랜잭션이 함께 가질  있다.

A사용자 ----> s-lock ---> DB <-------------- B사용자

B사용자 : s-lock이 걸렸네? 나도 s-lock을 걸고 데이터를 읽을  있겠다.

2. 베타락

- read 연산과 write 연산을 모두 실행 가능
- 베타 lock 연산을 실행한 트랜잭션만 해당 데이터에 대한 독점권을 가짐.

A사용자 ----> x-lock ---> DB <-------------- B사용자

B사용자 : x-lock이 걸렸네? 아무것도 못하고 기다려야겠군..

귀찮은데 LOCK을  단위로 하나 걸거나 작은 단위로 여기저기 걸어버리면 안될까??
==> 1. Blocking 문제점 발생한다.
(Blocking : 락들의 경합이 발생하여 특정 세션이 작업을 진행못하고 멈춘 상태)

why?
데이터에 대해서 하나의 트랜잭션이 베타락을 걸면
다른 트랜잭션들은 어떠한 락도 걸지 못하고 대기해야하기 때문에

블로킹이 풀리는 시점?
트랜잭션이 commit 혹인 rollback을  

블로킹의 해결방안
1. 트랜잭션을 짧게 정의
2. 같은 데이터를 갱신하는 트랜잭션이 동시에 수행되지 않도록 설계
3. LOCK TIMEOUT을 이용하여 잠금해제 시간을 조절


==> 2. 문제점 - 데드락 교착상태
x-lock과 s-lock이 무한대기가 걸려버린 상태
,   이상의 프로세스가 서로의 작업이 끝나기만을 기다리고 있어   영원히 끝나지 않는 상황

데드락 해결방안
1. 트랜잭션 진행방향을 같은 방향으로 처리
2. 트랜잭션 처리속도를 최소화
3. LOCK TIMEOUT을 이용하여 잠금해제 시간을 조절