잠금 타임아웃(Lock timeout)과 교착 상태(Deadlock)
MySQL(InnoDB) 기준으로 set innodb_lock_wait_timeout = 초단위;
명령어로 lock wait timeout 시스템변수를 설정 할수있다.
이때 만약에
트랜잭션A가 갱신을 했고, 트랜잭션B가 트랜잭션A가 갱신을 한 레코드에 갱신을 하려고 하면 wait가 발생하고 지정한 시간이 지나면 Lock timeout이 발생하고 다음과 같은 에러가 뜬다.
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
이것이 잠금 타임아웃(Lock timeout)이다.
- 타임아웃 시스템변수는 1초 이상부터 설정가능
- 타임아웃이 발생하는 경우 DBMS로부터 롤백되는 단위가 다를 때가있는데 트랜잭션 전체를 롤백하고 싶으면 명시적으로
rollback;
을 해주던가innodb_rollback_on_timeout
을 설정해줘야한다.
만약에
테이블 a와 테이블 b가 있을때
트랜잭션 A는 a에, 트랜잭션 B는 b에 갱신을 한 상태일때
트랜잭션 A가 b에 갱신을 하려하고, 이상태로
트랜잭션 B가 a에 갱신을 하려고하면 교착 상태(Deadlock) 가 발생하면서 다음과 같은 에러가 뜬다.
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
교착상태가 발생하면 타임아웃과 다르게 상황이 진전될 기미가 보이지 않기 때문에, DBMS에서는 교착 상태를 독자적으로 검출해 교착 상태를 보고한다. MySQL 같은 경우에도 교착 상태가 일어나면 즉시 시스템에 영향이 작은 쪽의 트랜잭션을 트랜잭션 개시 시점까지 롤백한다. (p217)
이런 교착상태를 줄이려면 여러가지 대책이 필요하다. 요약하자면 다음과 같다
클라/서버형 DBMS에는 타임아웃, 교착상태, 커넥션네트워크 오류, 일시오류 등 여러 트러블에 대한 대비책이 있어야한다.