이 글은 주로 다음과 같은 내용을 담고 있습니다.
(1) 트랜잭션의 개념과 ACID
(2) 거래 격리 수준
(3) MySQL에서의 트랜잭션
트랜잭션에 대한 이해는 다른 고급 개념의 기초입니다.
트랜잭션: 트랜잭션은 원자적 SQL 쿼리의 집합이거나 모두 성공하거나 모두 실패하는 경우 Roll을 이전 으로 반환합니다. 🎜>거래 상태입니다.
데이터베이스에서 ACID의 원자성, 일관성, 격리성, 내구성의 개념을 이해해 보겠습니다.
(1) 원자성: 트랜잭션의 작업은 분할할 수 없는 전체 단위로, 모두 완료되거나 아무것도 완료되지 않습니다.
(2) 일관성: 트랜잭션 실행 전후에 데이터베이스가 일관된 상태를 유지해야 합니다.
(3) 격리: 일반적으로 한 트랜잭션에서 수정한 내용은 최종 제출 전에 다른 트랜잭션에 표시되지 않습니다. 여기에는 트랜잭션 격리 수준 문제가 포함됩니다.
(4) 지속성: 일단 거래가 제출되면 수정 사항은 영구적이며 서버가 다운되더라도 영향을 받지 않습니다.
ACID를 더 잘 이해하기 위해 은행 계좌 이체를 예로 들어 보겠습니다.
-- 开始事务START TRANSACTION; -- 查询支票账户余额+ SELECT balance FROM checking WHERE customer_id = 10233276;+ -- 将支票账户减去200UPDATE checking SET balance = balance - 200.00 WHERE customer_id = 10233276; -- 将余额账户增加200UPDATE savings SET balance = balance + 200.00 WHERE customer_id = 10233276; -- 提交事务更新COMMIT;
원자성: 완전히 커밋하거나(예금 잔액 10233276이 200만큼 줄어들고 절감액이 200만큼 증가) 또는 완전히 롤백됩니다(두 테이블의 잔액은 변경되지 않음)
일관성: 이 예의 일관성은 데이터베이스 시스템이 실행되기 때문에 200위안이 되지 않는다는 사실에 반영됩니다. 세 번째 행 이후와 네 번째 행 이전에는 아직 커밋되지 않았기 때문에 충돌이 발생하고 사라지는 경우가 있습니다.
격리: 한 트랜잭션의 작업 문은 다른 트랜잭션의 문과 격리될 수 있습니다. 예를 들어 트랜잭션 A는 라인 3 이후 및 라인 4 이전에 실행되고 트랜잭션 B는 이때 당좌 잔액을 쿼리합니다. , 거래 A와 B가 서로 격리되어 있기 때문에 거래 A에서 차감된 200위안을 볼 수 있습니다(계좌 금액은 변경되지 않음). 트랜잭션 A가 커밋되기 전에 트랜잭션 B는 데이터 변경 사항을 관찰할 수 없습니다.
지속성: 이는 이해하기 쉽습니다. 즉, 거래가 제출된 후 수정 사항이 영구적입니다.
잠금과 같은 트랜잭션에는 많은 작업이 필요하므로 트랜잭션 지원이 필요한지 여부를 결정하고 필요에 따라 다른 스토리지 엔진을 선택할 수 있습니다.
SQL은 트랜잭션 내에서 표시되는 데이터를 제한하기 위해 네 가지 격리 수준을 정의합니다. 낮은 수준의 격리 수준은 동시성이 높고 시스템 오버헤드가 적다는 것은 분명하지만 데이터 보안 문제도 함께 발생합니다.
커밋되지 않은 읽기(uncommitted read)
이 격리 수준에서는 모든 트랜잭션이 커밋되지 않은 다른 트랜잭션의 실행 결과를 볼 수 있습니다. 커밋되지 않은 데이터를 읽는 것을 더티 읽기(dirty read)라고도 합니다. 이 수준은 거의 사용되지 않습니다.
읽기 커밋됨
이것은 대부분의 데이터베이스 시스템에 대한 기본 격리 수준입니다(MySQL 기본값은 아님). 이는 격리의 간단한 정의를 충족합니다. 즉, 트랜잭션은 커밋된 트랜잭션에 의해 변경된 내용만 볼 수 있습니다. 즉, 트랜잭션이 커밋되기 전에는 다른 트랜잭션에 표시되지 않습니다. 이 격리 수준은 반복 불가능한 읽기도 지원합니다. 동일한 트랜잭션의 다른 인스턴스가 이 인스턴스를 처리하는 동안 새로운 커밋을 가질 수 있으므로 동일한 선택 쿼리가 다른 결과를 반환할 수 있기 때문입니다.
반복 읽기(repeatable read)
이것은 MySQL의 기본 트랜잭션 격리 수준입니다. 동일한 트랜잭션의 여러 인스턴스가 가능하도록 보장합니다. 동시에 실행 데이터를 읽을 때 동일한 데이터 행이 표시됩니다. 그러나 이론적으로 이는 또 다른 까다로운 문제, 즉 팬텀 읽기(Phantom Read)로 이어집니다. 간단히 말해서, 팬텀 읽기는 사용자가 특정 범위의 데이터 행을 읽을 때 다른 트랜잭션이 해당 범위에 새 행을 삽입하는 것을 의미합니다. 사용자가 해당 범위의 데이터 행을 다시 읽으면 새로운 "팬텀"이 있음을 알게 됩니다. 좋아요. InnoDB와 Falcon 스토리지 엔진은 다중 버전 동시성 제어(MVCC, Multiversion Concurrency Control) 메커니즘을 통해 이 문제를 해결합니다.
직렬화 가능
이것은 트랜잭션이 순차적으로 실행되도록 강제하여 팬텀 읽기 문제를 해결합니다. . 즉, 읽은 각 데이터 행에 공유 잠금을 추가합니다. 이 수준에서는 시간 초과와 잠금 경합이 많이 발생할 수 있습니다.
이 4가지 격리 섹터를 MySQL에서 구현할 때 발생할 수 있는 문제는 다음과 같습니다.
MySQL의 기본값은 자동 커밋 모드(AutoCommit)를 채택하는 것입니다. 즉, 트랜잭션이 명시적으로 시작되지 않는 한 각 쿼리 작업은 커밋 작업을 수행하는 트랜잭션으로 처리됩니다.
AUTOCOMMIT 변수 를 설정하여 자동 커밋 모드를 활성화하거나 비활성화할 수 있습니다.
1로 설정하면 AUTOCOMMIT을 활성화하고 0으로 설정하면 AUTOCOMMIT를 비활성화합니다.
본 글의 주요 내용은 다음과 같습니다.
(1) 트랜잭션의 개념과 ACID
(2) 거래 격리 수준
(3) MySQL에서의 트랜잭션
위 내용은 고성능 MySQL의 트랜잭션 및 격리 수준에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!