이와 같은 단일 명령문은 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
".