Database/MYSQL

com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction

imsseong 2022. 11. 7. 17:05

에러:

Caused by: com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction

 

원인:

단일 트랜잭션의 수행 시간이 긴 경우

innodb lock wait timeout 값이 작게 설정된 경우

isolation level의 이슈인 경우

 

Isolation Level에는 다음의 4가지 단계가 있다.
Read Uncommitted: Transaction이 끝나지 않은 상황에서 다른 Transaction의 변경사항에 대한 조회가 가능하다.
Read Committed: Transaction이 끝나지 않은 데이터에 대한 조회(Select)의 경우 Shared Lock이 발생하며, Commit된 데이터만 조회가 가능하다.
Repeatable Read: Transaction의 Id를 기준으로 생성된 Snapshot 범위 내에서 데이터를 조회하기 떄문에 내용이 항상 동일함을 보장해준다.
Serializable: 가장 엄격한 Isolation Level로 모든 Transaction을 직렬화하여 처리한다.

 

Repeatable Read는는 첫 SELECT에서 해당 데이터에 Shared Lock을 걸고 데이터의 Shapshot을 생성 및 기록한다.

이후 동일 Transaction내의 SELECT는 Shanpshot에서 읽게 된다.

 

해결:

트랜잭션 수행 시간이 길다는 것은 비즈니스 로직을 처리하는 과정에서 불필요하게 트랜잭션을 잡았을 수도 있다는 것이다.

반복적으로 timeout이 발생하는 api나 쿼리가 있다면 로직 검토

코드 상의 문제가 없다면 innodb lock wait timeout 값을 변경

SET GLOBAL innodb_lock_wait_timeout=20;