집 >데이터 베이스 >MySQL 튜토리얼 >MySQL 데이터베이스 트랜잭션의 메커니즘 [요약]
지난 며칠간 인터뷰에서 데이터베이스 트랜잭션 메커니즘, 격리 수준, 낙관적 잠금 및 비관적 잠금에 대한 질문을 여러 번 받았습니다. 이전에 일부 개념이 아직 기억에 남아 있다고 말할 수 있습니다. 수준인데 이해가 안 되서 답변을 잘 못 드려요. 나중에 공부하려고 책을 다 읽고 몇 가지 이해한 부분이 있어서 여기에 기록으로 남깁니다.
거래란 무엇인가요?
내가 이해하는 거래는 완전한 비즈니스 행동입니다. 비즈니스 행동에는 여러 작업이 포함될 수 있습니다. 보다 전형적인 예는 은행 이체입니다. 계좌 A에서 계좌 B로 이체하려면 계좌 A에서 차감하고 계좌 B에 추가하는 두 가지 작업이 필요합니다. 이 두 가지 작업이 모두 완료되거나 둘 다 완료되지 않았는지 확인해야 합니다.
트랜잭션에는 다음을 포함한 ACID 특성이 있습니다.
● 원자성: 원자성이란 트랜잭션이 모두 성공하거나 모두 실패하거나 부분적으로 성공하지 않거나 부분적으로 실패하는 분할할 수 없음을 의미합니다. 중간에 오류가 발생하면 전장을 정리해야 합니다. 즉, 데이터를 롤백해야 합니다.
● 일관성: 일관성은 거래의 최종 결과를 말하며 데이터에 이상이 없음을 보장합니다. 일관성은 결과를 강조하며 원자성을 기반으로 합니다. 즉, 원자성이 보장되면 일관된 결과가 발생합니다.
● 격리: 격리는 트랜잭션이 제출되기 전에 다른 트랜잭션에 표시되지 않고 트랜잭션 간의 데이터가 격리되는 것을 의미합니다(물론 격리 정도는 수준에 따라 다릅니다).
● 내구성: 거래가 제출된 후에도 지속되며 오랫동안 저장될 수 있습니다.
트랜잭션 격리 수준
트랜잭션의 격리 수준을 이해하기 전에 데이터 읽기에 대한 몇 가지 개념을 이해해야 합니다.
● 더티 읽기: 다른 사람이 제출하지 않은 데이터를 읽는 것을 의미합니다.
● 반복 읽기: 같은 것 안에 있는 두 개의 쿼리입니다. 다른 사람이 쿼리의 기록을 수정하여 제출하면 두 번째 쿼리에는 표시되지 않으며, 두 쿼리 간에 불일치가 발생하지 않습니다. 같은 기록.
● 유령 읽기: 하나의 항목 안에 두 개의 쿼리가 있습니다. 다른 사람이 중간에 레코드를 추가하여 제출하면 두 번째 쿼리에서 찾을 수 있는 내용이 첫 번째 레코드와 일치하지 않게 됩니다.
트랜잭션 제어는 여러 수준으로 구분됩니다. 수준에 따라 격리 수준이 결정됩니다. MySQL은 다음과 같은 4가지 수준으로 구분됩니다.
● 커밋되지 않은 읽기: 이 수준은 트랜잭션 A의 수정이 트랜잭션 B에 커밋되지 않습니다. . 이는 가시적이며 데이터 읽기가 발생합니다. 이 유형은 일반적으로 사용되지 않습니다.
● 제출된 읽기: A 사물의 수정 사항은 제출된 후에만 B에게 표시됩니다. 이 경우 데이터를 가상으로 읽는 문제가 발생하며 두 쿼리의 결과가 달라집니다.
● 반복 읽기: MySQL의 기본 수준입니다. 이 수준에서는 두 쿼리 사이에 특정 레코드가 중간에 수정되어 다른 트랜잭션에 보이지 않게 됩니다. 그러나 새 트랜잭션의 경우 다른 트랜잭션이 표시되므로 새로운 팬텀 읽기가 계속 발생합니다.
● 직렬화 가능: 트랜잭션이 순차적으로 실행되며, 쿼리되는 각 레코드가 잠길 수 있으며 동시 상황에서는 심각한 성능 문제가 발생할 수 있으므로 일반적으로 이 유형은 사용되지 않습니다.
격리 수준 개요
트랜잭션의 격리 구현
트랜잭션의 격리는 두 가지 방법으로 제어됩니다. 하나는 시간에 따라 격리를 달성하는 잠금 방법이고, 다른 하나는 버전 제어입니다. 격리를 위해 여러 버전을 기록합니다.
1. 잠금
MySQL의 잠금은 읽기 잠금과 쓰기 잠금으로 구분됩니다. 읽기 잠금은 데이터를 읽기 때문에 여러 사람이 동시에 동일한 데이터를 읽을 수 있으며 쓰기 잠금에는 변경 사항이 포함됩니다. 따라서 다른 쓰기 잠금 및 읽기 잠금과 충돌하며 배타적입니다.
잠금 세분성 측면에서 테이블 수준 잠금과 행 수준 잠금은 테이블 수준 잠금과 행 수준 잠금으로 구분되며 일반적으로 테이블 구조가 수정되거나 테이블 전체가 업데이트될 때 발생하며 차단됩니다. 테이블에 대한 모든 읽기 및 쓰기 작업은 일반적으로 테이블 구조가 수정되거나 전체 테이블이 업데이트될 때 발생하며 지정된 레코드만 잠깁니다. 잠금 세분성이 작을수록 동시성이 높아져야 하며 테이블 잠금은 가능한 한 피해야 합니다. 이는 프로그램의 잠금 세분성과 동일한 원칙입니다.
2. 다중 버전 동시성 제어
성능상의 이유로 MySQL에는 행 수준 잠금 외에도 스토리지 엔진에 의해 구현되는 다중 버전 동시성 제어라는 또 다른 방법이 있습니다.
책에서는 하나의 레코드에 여러 버전을 사용하는 간단한 구현 방법을 설명합니다. 각 레코드에 두 개의 숨겨진 열이 추가되는데, 하나는 버전 번호를 생성하고 다른 하나는 매번 버전 번호를 삭제하는 것입니다. 트랜잭션이 열리면 트랜잭션 버전 번호가 할당되고 트랜잭션 버전 번호가 증가하며 이 버전 번호를 기준으로 트랜잭션 내의 작업이 비교됩니다. 세부 사항은 다음과 같습니다:
● 조회 시: 현재 거래 이전에 존재했던 레코드와 이번 거래로 생성되어 삭제되지 않은 레코드를 조회합니다. 즉, 생성 버전 번호 현재 버전 번호)
● 삽입 시: 기록된 생성 버전 번호는 현재 거래 버전 번호입니다.
● 삭제 시: 업데이트 기록의 삭제된 버전 번호는 현재 거래 버전 번호입니다.
● 업데이트 시: 새 레코드를 삽입하면 생성 버전 번호는 현재 거래 버전 번호이며, 원래 레코드 삭제 버전 번호를 현재 거래 버전 번호로 변경하면 삭제되었음을 의미합니다. 실제로 여기서의 업데이트는 다른 레코드를 삭제하고 추가하는 것과 같습니다.
3. 낙관적 잠금과 비관적 잠금
비관적 잠금은 사용 관점에서 비관적 잠금과 낙관적 잠금으로 나누어지며, 내가 찾은 데이터가 다른 사람에 의해 수정될 수 있다고 믿습니다. 쿼리할 때 이 데이터 배치는 다른 사람이 조작하지 못하도록 잠겨 있습니다. 낙관적 잠금은 매우 낙관적인 태도를 갖고 있으며 내가 찾은 데이터는 기본적으로 다른 사람이 수정할 수 없다고 생각하므로 쿼리할 때 이 데이터 배치는 잠기지 않습니다. 수정 사항을 제출할 때 다른 사람이 수정했는지 다시 확인하세요. 너무 늦기 전에 보완해도 늦지 않은 것 같습니다.
낙관적 잠금 및 비관적 잠금 구현:
● 비관적 잠금은 데이터베이스 수준에서 쉽게 해결할 수 있습니다. 쿼리 중에 데이터의 이 부분을 잠그려면 업데이트에 대해 select...를 사용하세요.
● 낙관적 잠금의 구현은 비관적 잠금보다 더 복잡합니다. 데이터베이스에 버전 번호 열을 넣을 수 있으며, 업데이트할 때 내가 찾은 데이터가 다른 사람에 의해 수정되었는지 확인하기 위해 버전 번호가 +1이 됩니다. 수정된 데이터가 수정되지 않았습니다. 업데이트 또는 프로그램에서 예외가 발생합니다.
낙관적 잠금을 사용해야 할까요, 비관적 잠금을 사용해야 할까요?
성능 측면에서 낙관적 잠금이 더 나은 성능을 보인다는 점을 고려하면 쿼리와 업데이트 사이에는 잠금 작업이 없지만 구현이 비관적 잠금만큼 간단하지 않고 오류가 발생할 수 있습니다. 발생하다. 그렇다면 고려해야 할 요소는 시스템의 동시성이 높은지 여부입니다. 갈등의 가능성은 얼마나 됩니까? 동시성이 높으면 낙관적 잠금을 사용하는 것이 좋으며, 그렇지 않으면 비관적 잠금과 같은 간단한 방법을 사용하는 것이 좋습니다.
추천 mysql 비디오 튜토리얼, 주소: https://www.php.cn/course/list/51.html
위 내용은 MySQL 데이터베이스 트랜잭션의 메커니즘 [요약]의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!