동시에 같은 DB Table row를 업데이트를 실행하면 교착상태(Deadlock)가 발생한다. 즉 둘 이상의 프로세스가 서로 작업이 끝나길 기다린다는 것이다. 멀티프로그래밍이 가능한 시스템에서 일어날 수 있는 현상이다. 뫼부우스의 띠 처럼 계속 한다는 것. 방어를 하기 위해서는 교착상태의 원인을 알아야 한다. 교착상태의 원인은 총 4가지이다.
상호배제(Mutual Exclusion): 한번에 한개의 프로세스만이 공유 자원을 사용할 수 있다.
점유와 대기 (Hold and Waite): 최소한 하나의 자원을 점유하고 있으면서 다른 프로세스에 할당되어 사용되고 있는 자원을 추가로 점유하기 이해 대기하는 프로세스가 있어야 한다.
3.비선점(Non-preemption): 다른 프로세스에 할당된 자원은 사용이 끝날 때까지 강제로 빼앗을 수 없어야 한다.
환형 대기(Circular Wait): 공유자원과 공유자원을 사용하기 위해 대기하는 프로세슷들이 원형으로 구성되어 있어 자신에게 할당된 자원을 점유하면서 앞이나 뒤에 있는 프로세스의 자원을 요구한다.
e.g --Process 1 UPDATE user SET email = 'userEmail@gmail.com' WHERE userId = 1; UPDATE item SET userId = 1 WHERE itemId = 2;
--Process 2 UPDATE item SET itemCode = '1234' WHERE itemId = 2; UPDATE user SET phone = '01012345678' WHERE userId = 1;
첫번째 transaction은 잘 된다. 문제는 두번째 transaction이다. Process 2번 UPDATE user SET 부분에서 Deadlock 상태가 일어난다.
그럼 본질문으로 들어와 방어하기 위해 어떻게 개발할 수 있을까?
e.g START TRANSACTION UPDATE user SET email = 'userEmail@gmail.com' WHERE userId = 1; UPDATE item SET userId = 1 WHERE itemId = 2; COMMIT;
START TRANSACTION
UPDATE item SET itemCode = '1234' WHERE itemId = 2;
UPDATE user SET phone = '01012345678' WHERE userId = 1;
COMMIT;
그리고 마지막에 에러가 있으면 ROLLBACK;을 사용해서 COMMIT전으로 돌아갈 수 있다. 트랜잭션을 짧게 작성히고 commit을 하면 데드락을 예방을 할 수 있다.