다중 사용자 데이터베이스의 등장과 함께 동일한 데이터를 동시 수정하는 것을 제한하는 과제가 발생했습니다. 이는 병렬 변경을 방지하고 데이터의 무결성을 유지하는 다양한 잠금 메커니즘(잠금 관리)의 출현으로 이어졌습니다.
액세스 제어가 없으면 동시 작업이 데이터 손상 또는 손실로 이어질 수 있습니다: 예를 들어, 두 개의 트랜잭션이 동시에 하나의 행을 업데이트하고, 한 트랜잭션의 변화가 손실될 수 있습니다. 충분히 엄격하지 않은 잠금은 경쟁 문제(경쟁 조건)를 초래하고, 과다한 잠금은 성능 저하(교착 상태, 경쟁)를 초래합니다.
현대의 DBMS에는 다양한 수준의 잠금(행 수준, 페이지 수준, 테이블 수준)과 다양한 모드(공유, 배타적, 업데이트)가 있습니다. 프로그래머는 트랜잭션 격리 설정 및 명시적 잠금 명령(예: SELECT ... FOR UPDATE)을 통해 이를 관리할 수 있습니다.
코드 예시:
-- 트랜잭션이 완료될 때까지 행을 잠금 BEGIN TRANSACTION; SELECT * FROM users WHERE id = 1 FOR UPDATE; UPDATE users SET name = 'New Name' WHERE id = 1; COMMIT;
주요 특징:
읽기 잠금(공유 잠금)과 쓰기 잠금(배타적 잠금) 간의 차이는 무엇인가요?
공유 잠금은 여러 트랜잭션이 동시에 데이터를 읽을 수 있도록 허용하지만, 변경은 허용하지 않습니다. 배타적 잠금은 오직 하나의 트랜잭션만 데이터 변경을 허용하고, 나머지 모든 트랜잭션은 접근을 금지합니다.
SELECT 명령이 잠금을 유발할 수 있나요?
일반적으로 SELECT는 잠금을 유발하지 않지만, SELECT ... FOR UPDATE를 사용하거나 높은 격리 수준(예: SERIALIZABLE)일 경우, DBMS가 행을 잠글 수 있습니다.
코드 예시:
SELECT * FROM products WHERE id = 10 FOR UPDATE;
잠금이 항상 "잃어버린 업데이트"를 방지하나요?
아니요, 잠금 수준이나 격리가 잘못 선택된 경우, 한 트랜잭션의 변경이 다른 트랜잭션으로 인해 손실되는 "잃어버린 업데이트"가 발생할 수 있습니다. 동시성 관리 메커니즘을 신중하게 선택해야 합니다.
분석 부서에서 두 프로그램이 동시에 주문 상태를 업데이트합니다. 빠른 처리를 위해 READ UNCOMMITTED 수준으로 설정하여 행을 잠그지 않았습니다. 이로 인해 충돌과 "잃어버린" 업데이트가 발생하여 일부 데이터가 손상되었습니다.
장점:
단점:
판매 부서에서 중요한 부분은 TRANSACTION + SELECT ... FOR UPDATE로 감쌌습니다. 행 수준에서 읽기 및 업데이트 작업을 분리했습니다.
장점:
단점: