mysql 고립 레벨 질문드립니다. 0 8 1,743

by Kun [MySQL] mysql isolation [2022.06.16 14:24:17]


안녕하세요. mysql로 프로젝트를 진행하던 중 궁금한 점이 있어서 문의를 남깁니다.

mysql 버전은 8 이며 InnoDB를 사용하고 있습니다.

현재 저는 delete 후 select 한 데이터를 insert 하려고 합니다.

delete -> insert into select 는 하나의 트랜잭션으로 묶어놓았습니다.

delete와 insert는 같은 테이블이며, select는 다른 여러 테이블들에서 데이터 값을 조합합니다.

 

1. 'REPEATABLE READ', 'SERIALIZABLE' 에서는 ER_LOCK_WAIT_TIMEOUT 이 발생합니다.

2. 'READ COMMITTED' 에서는 딜리트 되기 전의 값이 읽혀 삭제돼서 보이지 않아야 할 값도 insert 됩니다.

3. 'READ UNCOMMITED' 에서는 정상적으로 작동이 되나, 다른 트랜잭션의 커밋되지 않은 값도 읽히게 되어 위험하다고 판단이 됩니다.

 

락은 인서트 부분에서 발생하고 있습니다.

 

AFTER DELETE , AFTER INSERT 트리거를 생성하였을 경우엔 정상적으로 작동했습니다.

 

같은 트랜잭션 내의 커밋되지 않은 값만 읽어들이는 방법이 있을지 궁금합니다.

아니면 아예 트랜잭션을 풀고 작업을 진행해야 할까요?

by 신이만든지기 [2022.06.16 15:37:08]

delete 작업 중에 다른 트랜잭션에서  dml 트랜잭션이 들어와서  lock이 발생하는 것 같습니다.

차라리 delete 하는 작업중에 다른트랜잭션에서 수정하지 못하도록 lock(select for update)을 거는 것은 어떨런지요?

참고 : https://jinhokwon.github.io/mysql/mysql-select-for-update/


by Kun [2022.06.16 15:48:52]

답변 감사합니다! lock은 insert 하는 부분에서 발생하고 있습니다! 이 부분을 안적었네요 죄송합니다.


by pajama [2022.06.16 16:07:38]

제가 정확히 이해를 못한것일수도 있습니다만..

가능하다면 insert를 먼저 하고 delete를 하도록 순서를 바꾸는건 어떨지요?

아니면 말씀하신대로 delete/insert 트랜잭션을 분리하는 것이 방법일듯 합니다.


by Kun [2022.06.16 16:10:39]

show processlist; 쿼리를 날려보면 LOCK 걸린 부분의 쿼리가 INSERT ... 로 표시되고 있습니다.

 

같은 테이블이라서 딜리트 후에 인서트를 해야만 원하는 값을 얻을 수 있어서 순서 변경은 불가능할 것 같습니다. ㅠㅠ

 

답변 감사합니다. 분리하도록 하겠습니다!


by 우리집아찌 [2022.06.20 09:29:41]

INSERT 시 LOCK이 발생하는건 동일한 PK를 사용할때인데.. 

확인해보셨는지요?


by Kun [2022.06.20 13:36:06]

아하 그래서 LOCK이 발생했던 것 같습니다.

트랜잭션을 걸었던 이유도 같은 카테고리를 가지는 부분 전체를 삭제하고, 해당 카테고리 부분의 값을 다시 계산하여 넣었습니다.


by 우리집아찌 [2022.06.20 13:43:39]

mysql 에 sequence를 쓸수있다면 pk를 대체해보시고 안되면 auto increment를 사용하시면 문제가 없을것 같아요.


by Kun [2022.06.20 14:32:46]

시퀀스를 사용하지 않고, 아이디를 각 카테고리와 이름에 두고 사용입니다. 따로 id 항목으로 구분하진 않고 있습니다!

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입