본문 바로가기

DATABASE

데드락

이노디비 데드락 패턴


상호거래 데드락

트랜잭션 1에서 userId='A'에게 배타적 잠금 상태

트랜잭션 2에서 userId='B'에게 배타적 잠금 상태

이 상태에서 양쪽으로 배타적 잠금 요청시 발생.


유니크 인덱스 관련

트랜잭션 1,2,3이 다음과 같은 insert문 동시 실행

insert into tb values(9)


1번이 먼저 배타적 잠금을 가지고 있고, 그렇기에 트랜잭션 2,3번은 공유잠금을 획득하기 위해 대기.

1번이 롤백할 경우 가상의 레코드에 공유잠금을 획득, 그러나 없다는걸 알게되고 insert를 위해 2,3번이 동시에 배타적 잠금을 걸려고 시도.

하지만 두개의 트랜잭션이 모두 공유잠금 상태이기때문에 아무도 못걸고 데드락 발생.

http://kuaaan.tistory.com/100


외래키 잠금

a, b 두 테이블이 있고 b가 a의 키를 외래키로 참조.

b에 insert시 a에는 공유잠금이 걸림(외래키로인해)

이 상황에서 1번 트랜잭션이 a를 업뎃, 2번 트랜잭션이 a를 업뎃 하고자 하면..

위 유니크 인덱스패턴처럼 데드락이 발생


서로다른 인덱스로 인한 잠금

인덱스가 여러개일때(ex보조인덱스 1개, 기본키 1개)

하나의 업뎃문이 보조인덱스로 잠그고, 다른 업뎃문이 기본키로 잠그려고 하면

결국 동일한 레코드에대한 잠금 경합이 발생할 수 있음.


https://www.letmecompile.com/mysql-innodb-lock-deadlock/

http://gywn.net/2012/05/mysql-transaction-isolation-level/

https://m.blog.naver.com/PostView.nhn?blogId=reinstate10&logNo=130177937622&proxyReferer=https%3A%2F%2Fwww.google.co.kr%2F



낙관적 락

어플리케이션이 제공하는 락, 기본적으로 모든 요청은 업데이트를 시도한다.

하지만 시도 이후 잘못된 경우(버전 정보등이 안맞음) 잘못된 요청들을 모두 실패 시키는 방식.


비관적 락.

충돌이 날 것으로 가정하고 업데이트할 row에 일단 락을 걸고 시작.

한개의 row에 대해 여러 요청이 들어오는 경우 다른 요청들은 첫번째 요청이 락을 풀기 대기(보통 타임아웃 시간이 있고 시간이 지나면 실패로 들어감)

앞의 요청이 작업을 마치면 그다음 요청이 실행된다.