서로 다른 트랙잭션이 서로에 대한 락을 소유하게 되어 교착상태에 빠져서 다운되는 것
start transaction;
select * from log_login where id = 1 for update;

SELECT * FROM information_schema.INNODB_TRX;

start transaction;
select * from log_login where id = 2 for update;
SELECT * FROM information_schema.INNODB_TRX;

select * from log_login where id = 2 for update;
클라이언트 B 에서 락을 걸어준 리소스에 접근하였으므로, 대기하게 됩니다.
클라이언트 A 에서 발생시킨 트랜잭션의 상태가 LOCK WAIT 로 바뀐 것을 확인할 수 있습니다.

select * from log_login where id = 1 for update;
클라이언트 A 의 트랜잭션은 클라이언트 B 의 트랜잭션이 끝나길 기다리게 되고,
클라이언트 B 의 트랜잭션은 클라이언트 A 의 트랜잭션이 끝나길 기다리는 상태가 됩니다.
이 상태가 deadlock 이며, 다음과 같은 에러와 함께 트랜잭션이 종료됩니다.
(mysql 에서 기본적으로 deadlock 을 감지한 뒤 종료시키도록 세팅되어 있습니다.)

트랜잭션을 확인해보면 클라이언트 A 의 트랜잭션만 있는 것을 확인할 수 있습니다.


위는 프로젝트 꾸럼이에서 유저가 사용중인 상태에서 트랜잭션을 조회해본 스크린샷입니다.
project 테이블의 하나의 record 를 업데이트 하는 구문이 동시에 여러개가 들어올 때,
가장 아래쪽의 쿼리 (트랜잭션) 은 진행중 상태이므로, 이 쿼리 (트랜잭션) 이 작업중인 리소스에 락을 걸었습니다.
그 위에 있는 4개의 쿼리 (트랜잭션) 은 먼저 진행중인 쿼리 (트랜잭션) 이 끝나고 락이 풀리기를 대기하고 있는 모습입니다.
기본적인 select 구문에서는 락이 걸리지 않습니다.
select 에 for update 구문을 추가하게 되면 조건에 해당하는 레코드가 lock 이 걸리게 됩니다.
예시 )
SELECT * FROM log_login WHERE id = 1 FOR UPDATE;
예시 )
UPDATE employees SET salary = 50000 WHERE department = 'Sales';