Database/Mysql

스프링 부트 테스트 도중 'Lock wait timeout exceeded; try restarting transaction'

소프 2021. 8. 17.

스프링 테스트 코드를 아래와 같이 작성했다.

DB를 수정하는 테스트코드이기 때문에 트랜잭션을 걸어줬다.

 

코드는 보안상 대충 수정했다..

    @Transactional(value = "testTransactionManager") 
    @Test
    void updateTest() throws Exception {

        ReqDTO reqDTO = new ReqDTO();
        reqDTO.setTest("test");
        
        MvcResult mvcResult = super.performReqBody(BEGIN_URL, "test/insert", reqDTO);

        this.mockMvc.perform(asyncDispatch(mvcResult))
            .andDo(print())
            .andExpect(status().isOk())
            .andExpect(content().contentType(MediaType.APPLICATION_JSON))
            .andExpect(jsonPath("result").value(true))
            .andExpect(jsonPath("code").value("Success"))
            .andExpect(jsonPath("message").value("성공"))
			//...
    }

 

처음 한두번은 잘되다가 테스트 실행 도중 update 구문에서 lock이 걸리더니 타임아웃이 발생하면서 아래와 같은 에러가 떴다.

Lock wait timeout exceeded; try restarting transaction

 

참고글 1번을 보면서 아래 명령어를 수행했다.

select * from INFORMATION_SCHEMA.INNODB_TRX;

 

첫번째 두번쨰의 로우가 이질적이였다.

  • 어떻게 판단했냐면 프로그램이 실행중이 아니였는데도 특정 row의 trx_query가 빈값이였다.
  • 테스트코드에서 2개의 메소드가 락이 걸렸는데 딱 2개가 있었다.

해당 row의 trx_mysql_thread_id를 내 컴퓨터의 host 주소에 맞춰 id 값으로 조회해보니 존재하였따. 그래서 kill 한후 

테스트 코드를 돌려보니 잘 되었다.

 SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST where host like '%138%' and db = 'test_stage' and id = 2293031;
 SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST where host like '%138%' and db = 'test_stage' and id = 2291884;
 
 kill 2293031;
 kill 2291884;

 

추가로 해당 쿼리 결과에서 state가 ' Waiting for table metadata lock'에 해당하는 ID를 KILL 해주면 된다.

SELECT * FROM information_schema.processlist ORDER BY id ASC LIMIT 10;
kill 2755468;

 

 

★ 중요

인텔리제이서 디버깅을 진행하면서 한 트랜잭션안의 메소드에서 서버 혹은 디버깅을 강제종료하면 인텔리제이서 lock을 건상태로 남아있다. 왜냐하면 트랜잭션 걸린 메소드의 마무리되는 시점까지 진행이 되지않아 commit이 되지 않았기 때문이다.

 

테이블 설정을 아무리 만져도 소용없어서 해당 인텔리제이 프로젝트를 껐떠니 됨;

 

 

참고

https://www.popit.kr/mysql-lock-%EC%83%81%ED%99%A9-%EB%AC%B8%EC%A0%9C-%ED%95%B4%EA%B2%B0/

 

MySQL Lock 상황 문제 해결 | Popit

Lock wait timeout exceeded; try restarting transaction 문제 발생 시 어떻게 해결했는지 과정에 대해 설명한 글입니다.

www.popit.kr

 

https://hjjungdev.tistory.com/153

 

Mysql (Maria) Db 테이블락 확인하고 강제중지 방법.

1. 개요 보통 기본설정의 Rdbms는 Select문을 제외하고 Delete/Update/Insert문에 대해서 테이블 락을 걸게됩니다. 가령 A라는 사람이 Delete Table;의 명령문을 실행한 상태에서 커밋을 치지않는 다면 해당커

hjjungdev.tistory.com

 

'Database > Mysql' 카테고리의 다른 글

나만 헷갈리는 mysql8 함수  (0) 2022.10.06
인덱스 - 1  (0) 2022.01.10

댓글