• MySQL매뉴얼
    • MySQL 5.6 매뉴얼
    • MySQL 5.1 매뉴얼
    • MySQL 5.0 매뉴얼
    • MySQL HA 매뉴얼
  • 기술문서
    • Xtrabackup 구성
    • 메모리 사용량 모니터링
  • 라이선스
  • 온라인문의
  • 회사소개
  • → 목 록 (MySQL5.6 한글메뉴얼) [close]
  • 1. MySQL 5.6 새로운 기능
  • 2. MySQL 설치 및 업그레이드
  • 3. MySQL Tutorial
  • 4. MySQL 프로그램
  • 5. MySQL 서버관리
  • 6. 보안
  • 7. 백업 및 복구
  • 8. 최적화
  • 9. Language Structure(언어구조)
  • 10. Character Sets(Globalization)
  • 11. 데이터형(Data Types)
  • 12. 함수와 연산자
  • 13. SQL 문법
  • 14. InnoDB 스토리지 엔진
  • 1. InnoDB 소개
    2. InnoDB의 개념과 아키텍처
    1. MySQL 과 ACID 모델
    2. InnoDB 트랜잭션 모델 및 잠금
    3. InnoDB 잠금 모드
    4. 일관성 nonlock 읽기
    5. 잠금 읽기 (SELECT ... FOR UPDATE 및 SELECT ... LOCK IN SHARE MODE)
    6. InnoDB 레코드 격차 및 넥스트 키 잠금
    7. 넥스트키 로크에 의한 팬텀 문제 해결
    8. InnoDB의 다양한 SQL문에서 설정된 잠금
    9. 암시적 트랜잭션 커밋과 롤백
    10. 교착 상태 감지 및 롤백
    11. 교착 상태 해결 방법
    12. InnoDB 멀티 버전
    13. InnoDB 테이블 및 인덱스 구조
    3. InnoDB 구성
    4. InnoDB 관리
    5. InnoDB 테이블 스페이스 관리
    6. InnoDB 테이블 관리
    7. InnoDB 압축 테이블
    8. InnoDB 파일 형식 관리
    9. InnoDB Row Storage and Row Formats
    10. InnoDB 디스크 I/O 및 파일 영역 관리
    11. InnoDB와 온라인 DDL
    12. InnoDB 부팅 옵션 및 시스템 변수
    13. InnoDB의 성능
    14. InnoDB INFORMATION_SCHEMA 테이블
    15. InnoDB 모니터
    16. InnoDB 백업 및 복구
    17. InnoDB와 MySQL 복제
    18. InnoDB 및 memcached의 통합
    19. InnoDB 문제 해결
  • 15. 기타 스토리지 엔진
  • 16. 고가용성 및 확장성
  • 17. 리플리케이션
  • 18. MySQL Cluster
  • 19. 파티셔닝
  • 20. Stored Programs and Views
  • 21. INFORMATION_SCHEMA
  • 22. PERFORMANCE SCHEMA
  • 23. 컨넥터 및 API
  • 24. MySQL 확장
  • 25. MySQL Enterprise Edition
  • 26. MySQL Workbench
  • 27. 제약 및 제한
  • 28. MySQL 5.7 새로운 기능

14.2.5 잠금 읽기 (SELECT ... FOR UPDATE 및 SELECT ... LOCK IN SHARE MODE)

데이터 쿼리를 실행하고 동일한 트랜잭션 내에서 관련 데이터를 삽입하거나 업데이트 할 경우 일반 SELECT 문에서 충분한 보호가 제공되지 않습니다. 다른 트랜잭션 쿼리가 실행 된 직후 동일한 행을 갱신하거나 삭제할 수 있습니다. InnoDB 는 추가의 안전성이 제공되는 두 가지 유형의 잠금 읽기 가 지원되고 있습니다.

  • SELECT ... LOCK IN SHARE MODE 는 읽는 모든 행에 공유 모드 잠금을 설정합니다. 다른 세션도 그 행을 읽을 수 있지만 트랜잭션이 커밋 될 때까지 변경할 수 없습니다. 이러한 행 중 하나가 커밋되지 않은 다른 트랜잭션에 의해 변경된 경우, 쿼리는 트랜잭션이 끝날 때까지 기다렸다가 최신 값을 사용합니다.

  • 검색 인덱스 레코드가 발견되면 SELECT ... FOR UPDATE 는 행과 관련된 모든 항목을 잠급니다. 이 동작은 이러한 행에 UPDATE 문을 발행 한 경우와 동일합니다. 다른 트랜잭션은 이러한 행의 갱신, SELECT ... LOCK IN SHARE MODE 를 수행하거나 특정 트랜잭션 격리 수준에서 데이터의 읽기에서 차단됩니다. 일관성 독해는 읽은 뷰에있는 레코드에 설정된 잠금은 무시됩니다. (이전 버전의 레코드는 잠글 수 없습니다. 레코드 인 메모리 복사에서 Undo 로그 에 적용하여 재 구축됩니다.)

이 어구는 주로 단일 테이블 또는 여러 테이블로 분할 된 상태에서 트리 구조 또는 그래프 구조의 데이터를 처리 할 때 도움이됩니다. 에지 또는 트리 분기를 한 위치에서 다른 위치로 통과하고도 이러한 "포인터"다시 그 값을 변경할 수있는 권리를 보유하고 있습니다.

트랜잭션이 커밋 또는 롤백되면 LOCK IN SHARE MODE 및 FOR UPDATE 쿼리에 설정된 모든 잠금이 해제됩니다.

참고

SELECT FOR UPDATE 를 사용하여 업데이트 할 행 잠금은 START TRANSACTION 에서 트랜잭션을 시작하거나 autocommit 을 0으로 설정하여 자동 커밋이 비활성화되어있는 경우에만 적용됩니다. 자동 위탁이 활성화되어있는 경우는 스펙과 일치하는 행이 잠겨 없습니다.

사용 예

child 테이블에 새 행을 삽입하고 아이 라인이 parent 테이블에 부모 행을 가지고 있는지 확인한다고 가정합니다. 응용 프로그램 코드를 사용하여이 작업 시퀀스 전체의 참조 무​​결성을 보장 할 수 있습니다.

첫째, 일관성 독해를 사용하여 PARENT 테이블에서 쿼리를 실행하고 부모 행이 있는지 확인합니다. CHILD 테이블에 아이 라인을 안전하게 삽입 할 수 있습니까? 모르는 사이에 다른 어떤 세션에서 SELECT 와 INSERT 사이에 부모의 행이 삭제 된 가능성도 있기 때문에 할 수 없습니다.

이러한 문제의 가능성을 방지하려면 LOCK IN SHARE MODE 를 사용하여 SELECT 를 실행합니다.

 SELECT * FROM parent WHERE NAME = 'Jones'LOCK IN SHARE MODE;

LOCK IN SHARE MODE 쿼리에서 「Jones」 라는 부모가 반환되면 CHILD 테이블에 자식 레코드를 안전하게 추가 트랜잭션을 커밋 할 수 있습니다. PARENT 테이블의 응용 프로그램 행에서 읽거나 쓰려고 시도하는 트랜잭션은 사용자가 완료 될 때까지 (즉, 모든 테이블의 데이터가 일관성있는 상태가 될 때까지) 기다립니다.

또 다른 예는 CHILD 테이블에 추가 된 각 자에 고유 식별자를 할당 할 때 사용되는 CHILD_CODES 테이블의 정수 카운터 필드를 검토합니다. 일관성 읽기 또는 공유 모드 읽기를 사용하면 데이터베이스의 2 명의 사용자가 동일한 카운터 값을 참조 할 수 있으며, 2 개의 트랜잭션이 동일한 식별자를 가진 행을 CHILD 테이블에 추가하려고하면 중복 키 오류가 발생하기 때문에 카운터의 현재 값을 읽을 때는 사용하지 마십시오.

여기에서 2 명의 사용자가 카운터를 동시에 읽을 경우 적어도 1 명의 사용자가 카운터를 업데이트하려고하면 교착 상태가 발생하기 때문에 LOCK IN SHARE MODE 는 적절한 해결책이 없습니다.

카운터를 읽고 증가를 구현하려면 먼저 FOR UPDATE 를 사용하여 카운터의 잠금 읽기를 실행 한 후 카운터를 증가시킵니다. 예 :

 SELECT counter_field FROM child_codes FOR UPDATE;
 UPDATE child_codes SET counter_field = counter_field + 1;

SELECT ... FOR UPDATE 는 사용 가능한 최신 데이터를 읽고 읽은 각 행에 배타적 잠금을 설정합니다. 따라서 검색된 SQL UPDATE 에 의해 행에 설정되는 경우와 같은 잠금이 설정됩니다.

위의 설명은 단순히 SELECT ... FOR UPDATE 가 어떻게 기능 하는지를 보여준 예입니다. MySQL에서는 테이블에 단일 액세스를 사용하는 것만으로 고유 식별자를 생성하는 특정 작업을 수행 할 수 있습니다.

 UPDATE child_codes SET counter_field = LAST_INSERT_ID (counter_field + 1);
 SELECT LAST_INSERT_ID ();

이 SELECT 문은 단순히 (현재 연결 별) 식별자 정보를 취득 할뿐입니다. 어느 테이블에 액세스하지 않습니다.

서울시 강남구 영동대로 602 6층
TEL: 02-6061-0006  /  E: csr@mysqlkorea.com
주식회사 이노클러스터  등록번호 : 727-86-02261
Copyright © innocluster Co. ltd. all rights reserved