일반적으로 DeadLock(교착상태)을 설명하자면, 둘 이상의 프로세스가 다른 프로세스가 점유하고 있는 자원을 서로 기다릴 때 무한 대기에 빠지는 상황을 말한다. DB에서의 데드락은 두 트랜잭션이 각각 Lock을 정하고 다음 서로의 Lock에 접근하여 값을 얻어오려고 할 때 이미 각각의 트랜잭션에 의해 Lock이 설정되어 있기 때문에 양쪽 트랜잭션 모두 영원히 처리가 되지않게 되는 상태를 말한다.
즉, DB Deadlock은 상대방이 소유하고 있는 Lock을 요청해서 작업의 처리를 진행하지 못하는 상태다.
DataBase는 데이터를 영속적으로 저장하고 있는 시스템이다. 이런 시스템은 같은 자원(데이터)에 대해서 동시에 접근하는 경우가 생길 수 밖에 없고, 이럴 경우 데이터가 오염 될 수 있는데 그렇게 되지 않도록 데이터의 일관성과 무결성을 유지해야할 필요가 있다.
예를 들어 수강신청 시스템에서 1명만이 정원으로 남게되었는데, 2사람이 거의 동시에 버튼을 누른 경우, 성공은 1명만 되야한다. 즉, 동시성 제어으로 인해 트랜잭션 명령들 간의 끼어들기가 가능한 상황에서 서로 간섭 없이 독립적으로 수행되어 하기 때문에, DBMS(DataBase Management System)가 사용하는 공통적인 방법이 Lock인 것이다.
잠금(Locking)은 트랜잭션의 실행 순서를 강제로 제어하여 직렬 가능한 스케줄이 되도록 보장한다. 하지만 lock과 unlock을 잘못 사용하면 데드락 상태에 빠질 수 있는 것이다.
📚Shared Lock
📚Exclusive Lock
💡 Table-level → row-level으로 2단계로 lock 적용이유
이미 lock이 걸려있는 테이블에 다른 트랜잭션이 특정 row에 lock 거는 것 방지.row - level 상에서 lock이 걸린 상태(update,delete,,)일때 테이블 변경 방지.💡update 할때!
보통은 update되는 대상 row에 Lock이 걸리지만, where절에 인덱스를 적절히 태우지 않거나 인덱스가 없는 경우는 테이블 전체에 Lock이 걸린다.
update를 하기 위해서는 우선적 Shared Lock를 거치고 Exclusive Lock로 흘러간다.
→ 같은 행에 A트랜젝션은 sharedLock을 가지고 싶어하고 B트랜잭션은 Shared Lock에서 Exclusive Lock로 가야할 때 데드락 발생 가능성 있음
cf) 외래키에 의한 데드락
외래키는 부모테이블이나 자식 테이블에 데이터가 있는지 체크하는 작업이 필요하므로 잠금이 여러 테이블로 전파되고, 그로인해 데드락이 발생할 수 있다. 외래키 체크가 필요한 insert/update/delete에 대해서 Shared Lock을 설정
인덱스 설정 → 인덱스가 없으면 Lock이 걸리는 범위가 훨씬 넓어지기 때문에 교착상태가 발생하기 쉬워진다. ex) update
Isolation Level 조정
- 1) READ UNCOMMITED : Share-lock 사용안함.
- 2) READ COMMITED : 매번의 read 마다 Consistent read를 통한 새로운 snap shot을 생성하며, Share-lock을 사용안함
- 3) REPEATABLE READ : Shared Lock도 트랜잭션 종료시까지 지속된다. UPDATE, DELETE 상태일때 unique index에 대해 찾으면 → index record에만 lock (record lock)
range-type (범위로) 찾으면 → gap lock 사용
- 4) SERIALIZABLE : Shared Lock이 트랜잭션 종료시까지 지속된다.
Lock Timeout 설정 ( 트랜잭션 처리속도를 최소화 )
프로시저 우선순위 설정. 트랜잭션 진행방향을 같은방향으로 처리
데드락 발생시 DBMS는 둘 중 한 트랜잭션에 에러를 발생시킴으로써 문제를 해결.