둘 이상의 입력 또는 조작의 타이밍이나 순서 등이 공유자원에 동시에 접근
하여 결과값에 영향을 줄 수 있는 상태
은행 예시가 가장 피부에 와닿는다.
아들은 은행에 10000원의 잔고가 있었고, 현금 인출기를 통해 잔고 10000원을 출금하고 있다. 그 사이 엄마는 아들에게 용돈을 5000원 입금 해주었다. 그렇다면 잔고는 얼마일까?
아들은 10000원을 인출했기 때문에 잔고는 0원이 되고, 이후 엄마가 5000원을 입금해주신 덕분에 잔고는 5000원이 되리라 기대할 것이다.
하지만 경쟁상태일 때
동시에 출금과 입금이 이루어지는 경우
아들의 입장 : 현재잔고 10000원 – 10000원 출금 = 기대잔고 0원
엄마의 입장 : 현재잔고 10000원 – 5000원 입금 = 기대잔고 15000원
이처럼 경쟁상태는 공유 데이터(잔고)에 최종값을 보장할 수 없는 상황
을 말한다.
이 경쟁상태로 생기는 영역이임계구역(Critical Section)
이다.
공유 자원에 접근할 때 순서 등의 이유로 결과가 달라지는 영역이다.
이 임계구역을 해결하는 방법이 동기화 메커니즘(ex. 세마포어)
을 사용하는 것이다.
동기화 메커니즘의 근간이 바로 락(Lock)
을 사용하는 것이다.
경쟁상태(raceCondition)에서 서로 lock을 가졌을 때 생길 수 있는 상태
모든 작업들이 자원을 얻지 못해 다음 처리를 하지 못하는 상태로, '교착 상태'라고도 하며, 시스템적 작업(프로세스 or 스레드)들이 서로 필요한 자원을 한정적으로 서로 가지고 있을 때
발생한다.
그래서
두개 이상의 작업(프로세스 or 스레드)이 서로 상대방의 작업이 끝나기만을 wait하고 있기 때문에 아무도 작업을 끝내지 못하는 상태
위 그림과 같이 자동차(프로세스)들이 현재 위치한 길(자원)을 점유함과 동시에 다른 차가 사용하는 길(자원)을 사용하려고 대기하고 있지만, 다른 길(자원)을 사용할 수 없으며 현재 길(자원)에서도 벗어나지 못하는 원형대기상태이다.
데드락 상태가 되기 위해서는 다음 네 조건이 모두 충족되어야 한다.
한 번에 한 개의 프로세스만이 공유 자원을 사용할 수 있어야 한다.
-> 서로 lock을 사용할 수 있다는 말.
다른 프로세스에 할당된 자원은 사용이 끝날 때까지 강제로 빼앗을 수 없어야 한다.
-> 서로 lock을 사용할 수 있다는 말.
최소한 하나의 자원을 점유하고 있으면서 다른 프로세스에 할당되어 사용되고 있는 자원을 추가로 점유하기 위해 대기하는 프로세스가 있어야 한다.
공유 자원과 자원을 사용하기 위해 대기하는 프로세스들이 원형으로 구성되어 있어 자신에게 할당된 자원을 점유하면서 앞이나 뒤에 있는 프로세스의 자원을 요구해야 한다.
교착상태가 발생하지 않도록 사전에 시스템을 제어하는 방법
앞서 살펴본 교착상태 발생의 네 가지 조건 중 어느 하나를 제거함으로써 수행된다.
자원의 낭비가 심한 기법이다.
교착상태가 발생할 가능성을 배제하지 않고 교착상태가 발생하면 적절히 피해가는 방법으로, Banker's Algorithm이 사용된다.
현재 운영체제는 이 검출방식으로 사용하고 있다.
시스템에 교착상태가 발생했는지 점검하여 교착상태에 있는 프로세스와 자원을 발견하는 것.
그 중에는 타임아웃, 자원 할당 그래프 등을 사용할 수 있다.
추가적으로, JVM은 DB와 같이 데드락 상태를 추적하는 기능은 갖고 있지 않다. 따라서 자바프로그램에서 데드락이 생기면 완전히 멈춰버린다. 강제 종료시키는 방법 밖에 없다. (자바 병렬 프로그래밍 306P)
교착상태를 일으킨 프로세스를 종료시키거나, 교착상태의 프로세스에 할당된 자원을 선점(preempt)하여 프로세스나 자원을 회복하는 것
웹개발을 하면서 Deadlock 이슈는 DB에서 많이 발생하게 된다.
(물론 통신 네트워크에도 발생할 수 있는 이슈이다.)
운영체제에서는 프로세스가 deadlock이 걸린다면 DB에서는 트랜잭션이 deadlock이 걸리는 것이다.
DB의 트랜잭션을 활용하다보면 락이 필요하다. 해당 트랜잭션이 커밋될 때까지 락은 풀리지 않기 때문이다. 그래서 두개 이상의 트랜잭션이 데드락 상태에 빠지는 일은 충분히 가능하다.
트랜잭션이란 DB에서 일관성을 유지하기 위해 처리하는 최소한의 단위이다.
DB에서 deadlock 처리는 운영체제보다 복잡하다. DB에서는 데이터의 일관성이 정말 중요하다! 운영체제처럼 강제로 종료시키다던가 도 타임아웃
으로 프로세스를 종료되면 일부 데이터가 문제가 발생할 수 있다!
그래서 DB에서는 체크포인트
와 롤백
을 사용한다.
deadlock 발생 -> lock -> 체크포인트로 롤백
DB에서 Lock을 요청하면 체크포인트를 만들고 해당시점의 스냅샷을 저장한다. 그리고 잠금을 얻은 후에 작업을 계속 진행한다. 만약 lock에 타임아웃이 걸려서 프로세스를 중단하거나 lock을 포기해야 한다면 롤백을 사용하여 체크포인트 시점으로 시스템을 복귀시켜 데이터 유실을 막는다.
체크포인트 : 작업을 하다가 문제가 발생하면 저장된 상태로 되돌아오기 위한 표시.
체크포인트를 설정하면 현재의 시스템 상태가 하드디스크에 저장되는데, 이렇게 저장된 데이터를 스냅샷이라고 한다.
롤백 : 롤백은 작업을 하다가 문제가 발생하여 과거의 체크포인트로 되돌아 가는 것을 말한다. 롤백이 일어나면 저장된 스냅샷을 복원하여 시스템을 체크포인트 시점으로 되돌린다.
인덱스 설정, 테이블 정규화, Isolation Level 조정, Lock Timeout 설정,
프로시저 우선순위 설정 이 있다.
https://velog.io/@dd9s2/%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EA%B5%90%EC%B0%A9%EC%83%81%ED%83%9C-Deadlock
https://itpenote.tistory.com/624