inflearn logo
강의

講義

知識共有

10,000++億のデータを扱うカカオの面接官のMySQL

誰にでもわかる MySQL INSERT 上級ガイド

경쟁상태

解決済みの質問

3

Cola

投稿した質問数 45

0

INSERT INTO users (name, email, age, city)
SELECT '새 사용자', 'test메일', 25, 'seoul'
WHERE NOT EXISTS (
    SELECT 1
    FROM users
    WHERE email = 'test메일'
);

이 쿼리를 처음에 설명해 주실 때
두 개의 프로세스가 동시에 데이터를 확인하고 삽입하려 할 때 경쟁상태가 발생할 수 있다라고 하셨다가

뒤에 이 방식은 사실상 경쟁상태에 무관하다고 정정해주셨는데
그럼 두 개의 프로세스가 동시에 데이터를 확인하고 삽입하려 했을때 무관하다는 의미인가요??
왜 무관한지 잘 모르겠습니다.

mysql dbms/rdbms 데이터-엔지니어링 backend

回答 1

1

Hong

안녕하세요 Cola님 질문 남겨주셔서 감사합니다. 음 우선적으로 제가 촬영하면서 표현이 조금 과한 부분이 있는거 같네요. 조금 정정해서 설명을 드릴게요.


결론부터 말씀드리자면 이거는 트랜잭션 격리 수준에 따라서 다른요소입니다. Defaut인 REPEATABLE READ에서는같은 email이두번들어가는것까지는막아줍니다. 하지만경쟁상태와완전히무관한건아니고, 격리수준에따라결과가달라지며데드락이발생할수있습니다.


그럼 왜 REPEATABLE READ에서는중복이생기지 않을까?

여러분들이 사용하시는 일반 SELECT는 Lock없이 스냅샷 데이터를 읽지만, INSERT ... SELECT 안의 SELECT(여기 예시로는 NOT EXISTS 서브쿼리)는 조금 차이가 있습니다.


REPEATABLE READ에서 InnoDB는이 SELECT가읽는범위에공유(S) next-key 락을겁니다. 그래서 email = 'test메일'을찾는순간그값이들어갈자리에 즉 자리라는걸 갭이라고 표현하는데, 이 갭에락이걸리고, 그걸 갭 락이라고 불러요. 이러면 다른트랜잭션은그자리에 INSERT할수없게됩니다.


또 이렇게 락을 거는 읽기는 스냅샷이 아닌 최신 커밋 데이터를 읽기 떄문에, 먼저 실행된 트랜잭션이 커밋한 row를 후속으로 들어오는 트랜잭션이 볼 수 있죠.


그럼 진짜 트랜잭션이 동시에 실행되면 어떻게 될까?

이거는 제가 예시를 좀 들어보도록 할게요.

  • T1 : NOT EXISTS 확인 → 없음 → 해당갭에 S 락획득

  • T2: NOT EXISTS 확인 → 없음 → 같은갭에 S 락획득 (S 락끼리는호환)

  • T1: INSERT시도 → T2의 S 락때문에대기

  • T2: INSERT시도 → T1의 S 락때문에대기

    • 서로기다리는데드락 → InnoDB가감지해서한쪽을롤백 (한쪽은 애플리케이션 에러 발생)


  • 즉 결론은 한 건만 들어가고 중복은 생기지 않을꺼에요. 하지만 애플리케이션 상에서의 에러가 발생을 하게 되겠죠.


READ COMMITTED에서는 어떨까요??

해당 격리수준으로 가게 된다면, 이 SELECT는 락 없이 consistent read로 동작을 할 겁니다.

  • 그냥 일반 읽기로 해석하시면 됩니다.


그러면 앞선 예시에서 T1, T2 둘 다 "없음"을 확인하고 둘 다 INSERT해서 같은 건이 드렁 갈 수 있어요.


그래서 어떻게 막는가?

격리 수준에 영향을 받지 않고 중복을 막고 싶다면 UNIQUE 조건을 걸어버리시는게 가장 좋습니다.


그 다음에 INSERT IGNORE나 INSERT ... ON DUPLICATED KEY UPDATE를 쓰거나, 중복 키 에러 등등을 애플리케이션 레벨에서도 고려하시면 좋을꺼에요.


결론 : NOT EXISTS 방식은 UNIQUE 제약을 걸 수 없는 상황에서 쓰는 차선책이다.

0

Hong

추가로

https://dev.mysql.com/doc/refman/8.0/en/innodb-locks-set.html

해당 자료도 읽어보시면 도움이 되실꺼에요 ㅎㅎ


좋은 하루 보내세요!! 감사합니다!

stmt

0

5

1

실행 통계2 explain analyze 조인 쿼리

0

12

0

3강 인덱스 구조 강의 자료 문의

1

16

1

Kafka 4.0 zk 코드 제거 가이드 요청

0

9

1

조회 메서드에서 @Transactional(readOnly=true) 질문

1

20

1

19강 감정분석 강의처럼 api 돌렸는데

1

40

1

[해결됨]마지막 강의 내용 수정 화면이 기능을 못하네요.

0

27

1

[해결됨]부분적으로 화면 이동이 안되는 부분이 있습니다.

0

44

6

68강 문제 풀이

0

31

1

현대 쿼리 복잡성에 관한 질문

0

49

3

key_length 가 사용되는곳

0

39

1

낙관적락 질문있습니다.

0

43

1

해당 결제 부분을 포폴에서 테스트 api를 적용에 대한 궁금증

1

40

1

댓글순서부여방식

0

43

1

16강에서 코드가 계속 안도길래. ai가 고쳐서 일단 supabase에 preditc 한 주가를

1

43

1

공통 코드 VS Enum 클래스

1

39

1

movablePageCount와 pageSize 상수

0

36

1

16강 구글 colab 에서 코드 실행이 안돼요.

0

61

1

JPA와 네이티브 쿼리

0

41

1

인덱스 강의 혹은 해당 강의 전 듣어야 하는 사전강의 문의

0

80

2

라이브 운영중인 환경의 테이블에 인덱스 추가시 고려사항

0

109

2

오라클

0

110

1

21강에서 이해하기 어려운 부분들이 있습니다!

0

129

1

인덱스 분할, 병합에 따른 인덱스 적용 기준과 OPTIMIZE TABLE

0

154

2