>  기사  >  데이터 베이스  >  mysql 고급(4) mysql 선택

mysql 고급(4) mysql 선택

黄舟
黄舟원래의
2017-02-09 15:15:29947검색

mysql에서

select * for update

참고:

FOR UPDATE는 InnoDB에만 적용 가능하며 적용하려면 트랜잭션 블록(BEGIN/COMMIT)에 있어야 합니다.

함수

이 문으로 선택한 개체를 잠급니다. 이렇게 하면 선택 후 다른 곳에서 이러한 개체를 수정하여 발생하는 데이터 불일치를 방지할 수 있습니다. 통계(쿼리) 실행 중에 다른 사용자가 레코드를 업데이트하지 않도록

을 For update 절을 사용하여 잠글 수 있습니다. 이러한 방식으로 다른 사용자는 잠금이 해제되기 전에 이러한 레코드를 업데이트, 삭제 또는 잠글 수 없습니다.

deptno=25인 dept에서 daptno를 선택하세요.
FOR UPDATE를 사용하여 테이블을 잠그는 경우 커밋을 사용하여 잠긴 레코드를 해제해야 합니다.

잠금은 두 가지 범주로 나뉩니다: 잠금 범위 절과 잠금 동작 절 잠금 범위 절: select...for update 후에 of 절을 사용하여 선택 잠금 수행을 선택할 수 있습니다. 특정 데이터 테이블에 대한 작업. 기본적으로 of 절을 사용하지 않는다는 것은 select의 모든 데이터 테이블을 잠그는 것을 의미합니다. 잠금 동작 절: for update 작업을 수행할 때 일반 선택과 매우 다릅니다. 일반적으로 선택 시 데이터 잠금 여부를 고려할 필요가 없으며, 다중 버전 일관성 읽기 기능을 기반으로 최대 이전 버전을 읽습니다.
UPDATE 문에 대한 규칙은 쿼리 결과의 튜플을 잠급니다. 이 튜플은 이 트랜잭션이 커밋될 때까지 UPDATE, 삭제 및 다른 트랜잭션의 UPDATE에 의해 작동되지 않습니다.

응용 시나리오

그렇다면 업데이트는 언제 사용해야 할까요? 비즈니스 수준의 데이터가 독점되어야 하는 경우 업데이트에 사용하는 것을 고려할 수 있습니다. 기차표 예약과 같은 시나리오에서는 남은 티켓이 화면에 표시됩니다. 실제로 티켓을 발행할 때 다른 클라이언트에 의해 데이터가 수정되지 않았는지 다시 확인해야 합니다. 따라서 이 확인 과정에서 업데이트를 이용하실 수 있습니다. 이는 통일된 해결 문제이므로 사전 준비가 필요합니다.


InnoDB는 기본적으로 행 수준 잠금을 사용하므로 MySQL은 기본 키가 "명시적으로" 지정된 경우에만 행 잠금을 실행합니다(선택한 키만 잠김) ) 데이터 예) 그렇지 않으면 MySQL은 테이블 잠금(전체 데이터 형식 잠금)을 실행합니다.

예제 1

몇 가지 예를 들어보세요:

select * from t for update 会等待行锁释放之后,返回查询结果。
select * from t for update nowait 不等待行锁释放,提示锁冲突,不返回结果
select * from t for update wait 5 等待5秒,若行锁仍未释放,则提示锁冲突,不返回结果
select * from t for update skip locked 查询返回查询结果,但忽略有行锁的记录

SELECT...FOR UPDATE 문의 구문은 다음과 같습니다.
 

 SELECT ... FOR UPDATE [OF column_list][WAIT n|NOWAIT][SKIP LOCKED];

여기서:
 OF 절은 업데이트할 열을 지정하는 데, 즉 행의 특정 열을 잠그는 데 사용됩니다.
WAIT 절은 무기한 대기를 방지하기 위해 다른 사용자가 잠금을 해제할 때까지 기다리는 시간(초)을 지정합니다.

"USE FOR UPDATE WAIT" 절의 장점은 다음과 같습니다.
1. 잠긴 행에 대한 무기한 대기를 방지합니다. 2. 애플리케이션이 잠금 대기 시간을 더 많이 제어할 수 있습니다.
 3 이러한 사용자는 무기한 기다릴 수 없기 때문에 대화형 애플리케이션에 매우 유용합니다.
 4 건너뛰기 잠김을 사용하면 잠긴 행을 건너뛸 수 있으며 대기 n으로 인한 '리소스 사용 중' 예외 보고서는 보고되지 않습니다.

예 2

id와 name이라는 두 개의 필드가 있고 id가 기본 키인 제품 양식이 있다고 가정합니다.

예시 1: (기본 키를 명시적으로 지정하고 이 정보가 있으면 행 잠금)

SELECT * FROM products WHERE id='3' FOR UPDATE;
SELECT * FROM products WHERE id='3' and type=1 FOR UPDATE;

예 2: (기본 키를 명시적으로 지정하고 해당 정보가 없으면 잠금 없음)

SELECT * FROM products WHERE id='-1' FOR UPDATE;


예 2: (기본 키 없음, 테이블 잠금)

SELECT * FROM products WHERE name='Mouse' FOR UPDATE;


예 3: (기본 키가 명확하지 않음, 테이블 잠금 )

SELECT * FROM products WHERE id<>&#39;3&#39; FOR UPDATE;


예 4: (기본 키가 명확하지 않음, 테이블 잠금이 명확하지 않음)

SELECT * FROM products WHERE id LIKE &#39;3&#39; FOR UPDATE;


참고 1: FOR UPDATE는 InnoDB에만 적용 가능하며 적용하려면 트랜잭션 블록(BEGIN/COMMIT)에 있어야 합니다.

참고 2: 잠금 상황을 테스트하려면 MySQL의 명령 모드를 사용하여 두 개의 창을 열어 테스트할 수 있습니다.

이는 실제로 MySql 5.0에서 테스트한 경우입니다.

추가로: MyAsim은 테이블 수준 잠금만 지원하는 반면 InnerDB는 행 수준 잠금을 지원합니다.

(행 수준 잠금/테이블 수준 잠금) 잠금이 설정된 데이터는 다른 트랜잭션에서 잠글 수 없으며 테이블 수준 잠금인 경우 다른 트랜잭션에서 수정(수정, 삭제)할 수 없습니다. , 레코드 쿼리 여부에 관계없이 테이블이 잠깁니다.

또한 A와 B가 모두 테이블 ID를 쿼리했지만 레코드를 쿼리할 수 없는 경우 A와 B는 쿼리에 대해 행 잠금을 수행하지 않지만 이때 A와 B는 모두 배타적 잠금을 획득하게 됩니다. A 다른 레코드를 삽입하면 B가 이미 잠금을 갖고 있기 때문에 대기하게 됩니다. 이때 B는 동일한 데이터를 다시 삽입하고 잠금을 얻으려고 시도할 때 교착 상태가 발생합니다. 그런 다음 잠금을 해제합니다. 이때 A는 잠금이 성공적으로 삽입되었습니다.

지식 보충

잠금은 데이터베이스에서 매우 중요한 개념으로 다중 사용자 환경에서 데이터베이스의 무결성과 일관성을 보장하기 위해 주로 사용됩니다. 여러 사용자가 동시에 동일한 데이터베이스의 데이터를 조작할 수 있으면 데이터 불일치가 발생한다는 것을 알고 있습니다. 즉, 잠금이 없고 여러 사용자가 동시에 데이터베이스에 액세스하는 경우 트랜잭션이 동시에 동일한 데이터를 사용하면 문제가 발생할 수 있습니다. 이러한 문제에는 업데이트 손실, 더티 읽기, 반복 불가능한 읽기 및 팬텀 읽기가 포함됩니다.


1. 업데이트 손실 문제는 두 개 이상의 트랜잭션이 동일한 행을 선택한 다음 원래 선택한 값을 기반으로 해당 행을 업데이트할 때 발생합니다. 각 트랜잭션은 다른 트랜잭션의 존재를 인식하지 못합니다. 마지막 업데이트는 다른 트랜잭션의 업데이트를 덮어쓰므로 데이터 손실이 발생합니다. 예를 들어, 두 명의 편집자가 동일한 문서의 전자 사본을 생성합니다. 각 편집자는 자신의 사본을 독립적으로 변경한 다음 변경된 사본을 저장하고 원본 문서를 덮어씁니다. 자신의 변경 사항 사본을 저장한 마지막 편집자가 첫 번째 편집자의 변경 사항을 덮어씁니다. 첫 번째 편집자가 작업을 완료할 때까지 두 번째 편집자가 변경할 수 없는 경우 이 문제를 피할 수 있습니다.


2. 더티 읽기(Dirty reading)는 트랜잭션이 데이터에 액세스하고 데이터를 수정했지만 수정 사항이 아직 데이터베이스에 제출되지 않은 경우 다른 트랜잭션도 해당 데이터에 액세스한 후 사용되는 것을 의미합니다. 이 데이터. 이 데이터는 아직 커밋되지 않았기 때문에 다른 트랜잭션에서 읽은 데이터는 더티 데이터이며 더티 데이터를 기반으로 한 작업이 올바르지 않을 수 있습니다. 예를 들어, 편집자는 전자 문서를 변경하고 있습니다. 변경 프로세스 중에 다른 편집자가 문서의 복사본을 만들고(사본에는 지금까지 변경된 내용이 모두 포함되어 있음) 이를 의도된 사용자에게 배포합니다. 이후 첫 번째 편집자는 지금까지의 변경 사항이 잘못되었다고 판단하여 편집 내용을 삭제하고 문서를 저장했습니다. 사용자에게 배포된 문서에는 더 이상 존재하지 않으며 존재한 적이 없는 것으로 간주되는 편집 내용이 포함되어 있습니다. 첫 번째 편집자가 변경 사항을 완료할 때까지 아무도 변경된 문서를 읽을 수 없으면 이 문제를 피할 수 있습니다.


3. 반복 불가능 읽기는 트랜잭션 내에서 동일한 데이터를 여러 번 읽는 것을 의미합니다. 이 트랜잭션이 끝나기 전에 다른 트랜잭션도 동일한 데이터에 액세스합니다. 그러면 첫 번째 트랜잭션에서 두 번 읽은 데이터 사이에 두 번째 트랜잭션의 수정으로 인해 첫 번째 트랜잭션에서 두 번 읽은 데이터가 다를 수 있습니다. 이와 같이 트랜잭션 내에서 두 번 읽은 데이터가 다르기 때문에 반복 불가능 읽기라고 합니다. 예를 들어, 편집자는 동일한 문서를 두 번 읽지만, 읽는 사이에 작성자는 문서를 다시 작성합니다. 편집자가 문서를 두 번째로 읽으면 문서가 변경된 것입니다. 원시 읽기는 반복할 수 없습니다. 작성자가 모든 작성을 마친 후에만 편집자가 문서를 읽을 수 있으면 이 문제를 피할 수 있습니다.


4. 팬텀 읽기(Phantom Read)는 트랜잭션이 독립적으로 실행되지 않을 때 발생하는 현상을 의미합니다. 예를 들어 첫 번째 트랜잭션이 테이블의 데이터를 수정하는데, 이 수정에는 테이블의 모든 데이터 행이 포함됩니다. 동시에 두 번째 트랜잭션도 이 테이블의 데이터를 수정합니다. 이 수정으로 인해 테이블에 새 데이터 행이 삽입됩니다. 그러면 나중에 첫 번째 트랜잭션을 수행한 사용자는 마치 환각이 발생한 것처럼 테이블에 아직 수정되지 않은 데이터 행이 있다는 것을 알게 될 것입니다. 예를 들어, 편집자는 작성자가 제출한 문서를 변경했지만 프로덕션에서 변경 내용을 문서의 마스터 사본에 병합할 때 작성자가 편집되지 않은 새 자료를 문서에 추가했음이 발견되었습니다. 편집자와 제작 부서가 원본 문서 작업을 마칠 때까지 누구도 문서에 새 자료를 추가할 수 없다면 이 문제를 피할 수 있습니다.


따라서 여러 사용자의 동시 접근을 처리하는 방법은 잠금입니다. 잠금은 다른 트랜잭션이 지정된 리소스 제어에 액세스하는 것을 방지하고 동시성 제어를 달성하는 주요 수단입니다. 사용자가 데이터베이스의 개체를 잠그면 다른 사용자는 더 이상 해당 개체에 액세스할 수 없습니다. 동시 액세스에 대한 잠금의 영향은 잠금의 세분성에 반영됩니다. 잠긴 자원을 제어하기 위해서는 먼저 시스템의 공간 관리를 이해해야 합니다.

위 내용은 Advanced mysql(4)의 mysql select 내용입니다. 더 많은 관련 내용은 PHP 중국어 홈페이지(www.php.cn)를 참고해주세요!


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.