낙관적 Lock과 비관적 Lock
낙관적 잠금
낙관적 잠금은 충돌이 드물고 전체 트랜잭션 중에 리소스를 잠글 필요가 없다고 가정하는 전략입니다.
대신 트랜잭션이 커밋될 때 충돌을 확인합니다.
충돌이 감지되면(예: 다른 트랜잭션이 데이터를 수정함) 트랜잭션이 롤백되고 오류가 반환됩니다.
낙관적 잠금은 버전 번호를 사용하여 구현됩니다.
트랜잭션이 커밋되면 시스템은 데이터베이스의 현재 버전 번호가 읽은 버전 번호와 일치하는지 확인합니다.
일치하면 트랜잭션이 커밋되고 버전 번호가 증가합니다.
일치하지 않으면 충돌이 발생하고 트랜잭션이 롤백됩니다.
다음은 낙관적 잠금을 사용하는 방법의 예입니다.
START TRANSACTION;
SELECT version_number FROM table_name WHERE condition;
-- Do some work...
UPDATE table_name SET column_name = new_value, version_number = version_number + 1 WHERE condition AND version_number = previously_read_version_number;
COMMIT;
비관적 잠금
비관적 잠금은 충돌 가능성이 있다고 가정하고 리소스에 액세스하는 즉시 리소스를 잠그는 전략입니다
트랜잭션이 레코드를 읽고 나중에 업데이트할 계획이라면 즉시 해당 레코드를 잠급니다.
이렇게 하면 잠금이 해제될 때까지 다른 트랜잭션이 수정하지 못합니다.
보통, 동시성 제어를 위해서 가장 보편적인 방법은 락을 통한 줄세우는 즉 비관적 잠금입니다
하지만, 비관적 잠금은 충돌을 방지할 수 있지만 동시성과 잠재적 잠금 경합이 감소하는 대가를 치릅니다.
충돌이 일반적이고 충돌로 인해 트랜잭션이 롤백되지 않는 것이 중요한 시스템에서 자주 사용됩니다.
Ex. 동시성이 빈곤하지 않은 쿼리로 인해 다른 쿼리가 대기하는 상황
다음은 비관적 잠금을 사용하는 방법의 예입니다
START TRANSACTION;
SELECT * FROM table_name WHERE condition FOR UPDATE;
-- Do some work...
UPDATE table_name SET column_name = new_value WHERE condition;
COMMIT;
이 예에서 ‘FOR UPDATE’ 절은 선택한 행에 대한 쓰기 잠금을 획득합니다. 다른 트랜잭션은 잠금이 해제될 때까지 이러한 행을 수정할 수 없습니다
부족한 점이나 잘못 된 점을 알려주시면 시정하겠습니다 :>
'DEV > Backend' 카테고리의 다른 글
ESP (0) | 2023.06.10 |
---|---|
Write Lock과 Read Lock (0) | 2023.06.10 |
동시성 제어 (1) | 2023.06.10 |
트랜잭션 격리레벨 (0) | 2023.06.10 |
트랜잭션(Transaction) (0) | 2023.06.10 |