MySQL : 트랜잭션이 행을 잠글 것인가?


13

이전에 MySQL 트랜잭션을 사용해 보지 않았으며 무언가를 명확히하고 싶습니다.

두 명의 사용자가 정확한 시간에 쿼리를 실행한다면 MySQL은 어떻게 이것을 처리합니까? 예를 들어 사용자가 레코드를 업데이트하려고합니다.

user1 : 업데이트 테이블 세트 column = column-4 여기서 column_id = 1;

user2 : 업데이트 테이블 세트 column = column-7 여기서 column_id = 1;

이제 트랜잭션을 사용하면 MySQL이 먼저 실행될 쿼리를 선택하고 첫 번째 쿼리가 커밋 될 때까지 두 번째 사용자를 잠 그게됩니까? 이것이 테이블 잠금 또는 행 잠금입니까?

세 번째 사용자가 select 문을 발행하면 어떻게됩니까? MySQL이 돌려주는 가치는 무엇입니까?

추신 : 이것은 Innodb에 있습니다.

답변:


17

이와 같은 단일 명령문은 MyISAM 또는 InnoDB, 트랜잭션 또는 autocommit = ON과 동일하게 작동합니다. 쿼리를 수행하기에 충분하게 차단하여 다른 연결을 차단합니다. 완료되면 다른 연결이 진행됩니다. 모든 경우에, 컬럼은 곧 11만큼 감소합니다.

세 번째 사용자는 0 또는 4 또는 7 또는 11만큼 값이 감소한 것을 볼 수 있습니다. "매우 정확한 시간"은 각 ​​문장의 실행 시점에서 단일 스레드 잠금이 검사 / 설정 / 무엇이든간에 실제로 불가능합니다. . 그것이 그들이 인 것이다 단지 너무 빨리 당신이 그것을 볼 수 없습니다, 직렬화.

InnoDB는 테이블이 아닌 행만 잠급니다. (OK, DDL 문은 대담한 잠금을 수행합니다.)

더 흥미로운 것은 두 가지를 수정하거나 눈에 띄는 시간이 걸리는 트랜잭션입니다.

의도 사례 : 단일 품목이지만 시간이 걸리는 경우 :

BEGIN;
SELECT something;
think about it for a while
UPDATE that something;
COMMIT;

선택은 다음과 같이 작성되어야합니다.

SELECT something  FOR UPDATE;

이것은 다른 연결에 "행을 업데이트하려고합니다. (많은 초보자들이이 미묘함을 그리워하기 때문에이 예를 제시합니다.)

교착 상태 사례 : 2 가지 문제 :

BEGIN;    -- in one connection
UPDATE thing_1;
UPDATE thing_2;
COMMIT;

BEGIN;    -- in another connection, at the "exact same time"
UPDATE thing_2;
UPDATE thing_1;
COMMIT;

이것은 교착 상태의 전형적인 예입니다. 각각 교착 상태에 도달 한 다음 다른 것에 도달합니다. 분명히 작동하지 않습니다. 하나의 트랜잭션이 종료되었습니다. 다른 하나는 완료됩니다. 따라서 오류 확인 해야 오류를 발견 할 수 있습니다.

교착 상태에 대한 일반적인 반응은 전체 실패한 트랜잭션을 재생하는 것입니다. 그러면 다른 연결이 방해받지 않고 문제없이 진행됩니다. (다른 연결은 또 다른 교착 상태를 만들 수 있습니다.)

지연 사례 : 두 연결이 동일한 순서로 여러 항목을 가져 오는 경우 다른 연결이 완료 될 때까지 하나를 지연시킬 수 있습니다. 이것을 "영원히 기다리지"않기 위해 기본값은 50 초 innodb_lock_wait_timeout입니다. 당신의 간단한 쌍 UPDATEs은 실제로이 경우의 예입니다. 하나는 즉시 끝날 것입니다. 다른 하나는 첫 번째가 끝날 때까지 정지됩니다.

사용자가 터치하는 것을 일관되게 주문하여 교착 상태가 (일부 경우) 지연으로 전환되는 방법에 유의하십시오.

자동 커밋 = 1 : 이 설정 호출하지 않고는 BEGIN, 각 문은 효율적입니다 :

BEGIN;
your statement
COMMIT;

autocommit = 0 : 발생 대기 문제입니다. 쓰기 쿼리를 수행하면 BEGIN암시 적으로 생성됩니다. 그러나 결국을 발행하는 것은 귀하의 책임 COMMIT입니다. 그렇게하지 않으면 왜 시스템이 중단되었는지 궁금해 할 것입니다. (또 다른 일반적인 초보자 버그.) 내 충고 : "사용하지 마십시오 =0".

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.