데이터베이스 가져 오기 (MySQL의) : 트랜잭션

  • 논리 아키텍처 MySQL의 서비스
  • ACID 트랜잭션
  • 트랜잭션 로그
  • 트랜잭션 격리 수준
  • 교착 상태
  • MVCC
  • MySQL의 트랜잭션

 첫째, 논리적 아키텍처 MySQL의 서비스

는 SQL 트랜잭션을보고하는 것이 전제 조건이어야합니다 MySQL의 서비스 조직의 논리를 이해하기 전에 왜 트랜잭션 메커니즘, 그것은 당신을 말할 것이다. 어떻게 거래 업무를 이해함으로써, 그것이 문제, 이러한 문제 뒤에 근본 원인을 해결할 수없는 문제를 해결할 수 있습니까? 둘 다 논리 아키텍처 서비스에서 트리거를 필요로한다.

1.1MySQL 서비스 로직 차트 :

출처 : https://blog.csdn.net/fuzhongmin05/article/details/70904190 , MySQL의 성능 최적화에 대한도이 블로그를 참조 할 수 있습니다.

MySQL은 일반적으로 세 가지 논리 구조로 나누어, (또한 일반적으로 클라이언트로 함) 최상위 서비스는 MySQL의에 고유하지 않습니다, 대부분의 기반 도구 나 서비스 네트워크 클라이언트 / 서버는 유사한 구조를 가지고있다. 이러한 연결 처리, 권한 부여 및 인증, 보안 등.

두 번째 계층 아키텍처는 쿼리 구문 분석, 분석, 최적화, 캐싱을 포함하여 MySQL의 서비스 기능의 핵심이며, 모든 내장 함수 (예를 들어, 날짜, 시간, 수학 및 암호화 기능), 모든 교차 저장소 엔진의 기능이 계층에서 실현된다 : 저장 프로 시저, 트리거, 그리고 다른 전망을 제공합니다.

MySQL의 데이터 저장 및 검색을 위해 스토리지 엔진 최저치. 그리고 리눅스 파일 시스템과 유사한 아래, 각 스토리지 엔진은 장점과 단점이 있습니다. 스토리지 엔진 API와 통신하는 중간층을 통해 서비스의 API 인터페이스는 이러한 차이가 상층에 투명한 절차 조회되도록 다른 스토리지 엔진 차이를 차폐. 저장소 엔진 API는 이러한 "트랜잭션을 시작"또는 "행 추출 된 기본 키"및 기타 작업을 수행하는 등의 기능을 기본 수십 포함되어 있습니다. 하지만 해결 스토리지 엔진 SQL에 서로 다른 스토리지 엔진 간의 상호 통신, 단순히 각각의 상위 서버를 요구하지 않습니다 (InnoDB의 제외하고는 외래 키 자체가이 기능을 구현하지 않습니다 MySQL 서버로 정의 구문 분석) .

1.2 동시성 제어 :

각 클라이언트 시작하는 서버 측 연결하여 새로운 요청 / 도구를 스레딩하는 새로운 메모리 공간을 클라이언트의 요청을 받아 개방에 대한 책임, 서버의 메모리에 새 스레드를 생성 할 때 서버에 각 사용자 커넥트 클라이언트 요청에 응답하기위한 프로세스 주소 공간 풀에서 새 스레드를 생성 할 때, 사용자 시작 쿼리 메모리 공간의 스레드를 실행하고,이 또한 캐시의 결과이며 서버에 돌려 보냈다. 스레드 재사용 파괴는 접속 / 스레드 처리 관리자에 의해 달성된다.

단순히 사용자 동수 요청을 넣고, 연결 / 스레드 프로세서가 메모리 공간을 열어, 쿼리를 시작하는 메커니즘을 제공한다.

서비스 계층 및 스토리지 엔진 층 : 요청 여러 사용자가 동수 인 경우, 가능한 동시, MySQL의 동시성 제어 두 가지 수준으로 존재해야한다. 예를 들어 전자 우편 상자 유닉스 시스템에서, MBOX는 사서함의 모든 메시지는 함께 끝까지 서로 끝을 교차. 전자 메일 메시지와 매우 친절 분석하고, 메일의 전달을 읽기위한이 형식은 파일의 끝은 새 메시지의 내용이 될 수 있습니다 추가 한대로 매우 쉽게이기도합니다.

동시에 두 개의 프로세스가 동일한 사서함에 메일을 배달하는 경우에, 오른쪽이 오류가 발생했습니다 동시 데이터이다 사서함 파일의 끝 부분에 부착 된 교차합니다. 좋은 메일 배달 시스템은 잠금 (잠금)에 의해 데이터 손상을 방지하기위한 것입니다. 메일의 전달 및 메일로 고객이 다른 고객이 잠겨있는 경우 잠금이 전달하기 위해 해제 될 때까지 기다려야합니다.

이 실제 응용 프로그램 환경 비록 프로그램이 잘 작동 잠금 장치,하지만하지 않습니다 지원 동시 처리를 누르고 있습니다. 한 번 때문에, 하나의 프로세스 만이 사서함 시스템의 많은 수에서 문제가 데이터 메일 박스를 수정할 수 있습니다.

 1.3 잠금 장치 :

 1.3.1 읽기 - 쓰기 잠금

동시에 여러 사용자가 동일한 전자 메일을 읽을의 과정은 문제가되지 않지만이 경우 사서함 사용자는 사용자의 또 다른 그림은 결정되지 결과가 될 것입니다 무슨 메시지 번호 (25)를, 삭제, 읽기 때 . 오류를 철회 할 수 읽기 고객, 그것은 사서함 데이터 불일치로 읽을 수 있습니다. 사서함 데이터베이스의 테이블로 볼 경우, 전자 메일은 행으로, 같은 문제는 또한 데이터베이스에 존재합니다. 이 문제에 대한 해결책은 동시 읽기 또는 쓰기 다루는 잠금 두 종류로 이루어진 시스템을 고정하여 문제를 해결하기 위해, 동시 제어 할 수있다. 잠금이 두 가지 유형은 일반적으로도 읽기 및 쓰기 잠금으로 알려진 공유 잠금 및 독점 잠금이라고합니다.

읽기 잠금 : 잠금 읽기는 공유하거나 서로를 차단하지. 여러 사용자가 간섭하지 않고, 동시에 같은 리소스를 읽을 수 있지만 쓰기를 차단 잠금을 읽을 수 있습니다.

쓰기 자물쇠 기입 로크는 쓰기 잠금 다른 기록을 차단하는 수단 읽어 배타적이다.

1.3.2 잠금 단위 :

데이터가 이상적으로 수정 될 수있는 데이터의 일부를 고정하려고 노력하지만, 모든 리소스를 잠글, 읽기 및 쓰기 잠금의 잠금 단위는 범위를 의미합니다. 예를 들어, 행 로킹 ​​언제든지 더 로크 테이블 이상으로, 주어진 자원에, 데이터의 적은 양이 길고 서로하지 충돌이라고하면 충돌만큼 (동시 시스템의 더 높은 정도가 될 수 있고, 잠금 교착 상태는) 나중에 소개합니다.

그러나 모든 이상적인 이상적인 후, 결국, 자원의 소비를 잠글 필요가있다. 시스템의 비용을 증가시킬 것이다 락이 등 잠금을 해제 해제되었는지 잠금을 획득하는 검사 : 다양한 조작 포함 잠금. 시스템 잠금이 아닌 데이터에 대한 액세스를 관리 할 수있는 시간이 많이 걸리는 경우, 해당 시스템의 성능도 영향을받습니다.

그래서, 어떤 당신은 비용과 안전 잠금 장치 사이의 균형을 추구해야합니다. 대부분의 상용 데이터베이스 시스템 더 많은 선택을 제공하지 않습니다는 일반적으로 잠금의 경우 비교적 많은 수에서 더 나은 성능을 제공하기 위해, 테이블에 행 수준 잠금을 적용, 복잡한 다양한 방법으로한다. 그러나 MySQL은 다양한 옵션을 제공하고, MySQL의 스토리지 엔진의 각각 자신의 전략 및 잠금 잠금 단위를 구현할 수 있습니다.

테이블 잠금 : 서로 읽기 잠금을 차단하지 않는, 더 쓰기 잠금이없는 경우에만 잠겨 읽기 잠금을 얻기 위해 다른 사용자를 읽은 전에 (업데이트 등을 삭제, 수정, 삽입) 전체 테이블을 작성합니다.

행 수준 잠금 : 현재 운영 행 잠금의 값.

테이블 잠금 최저 비용 전략이지만, 아직 동시성에 매우 큰 제한, 특정 시나리오에서 테이블 잠금도 좋은 성능을 가질 수있다. READ LOCAL 테이블의 예를 특정 유형에 대한 동시 동작을 지원한다. 또한, 판독 로크보다 높은 우선 순위보다 쓰기 잠금 판독 로크는 쓰기 잠금의 전방에 삽입 될 수없는 반면, 기입 로크 요청은 판독 로크 앞에 삽입 될 수 있도록있다. 테이블 잠금이 큰 장면을 쓰는 것이 더 적합 할 수있다. 자신의 관리 스토리지 엔진 잠금 장치에도 불구하고, MySQL은 자체는 여전히 다른 목적을 달성하기 위해 효과적인 잠금 테이블의 다양한 사용합니다. 예를 들어, 서버가 스토리지 엔진 잠금 메커니즘을 무시하고, 테이블 잠금 값 클래스를 사용하여 ALTER 표 문으로합니다.

행 레벨의 잠금 및 이노 XtraDB 및 다른 저장 기관에서 로우 레벨 잠금을 달성 최대화하는 동시 처리를 지원할 수있다. 행 수준에서 잠금 스토리지 엔진 층은 달성하지만, MySQL은 서비스 계층을 구현하지 않습니다.

 둘째, 트랜잭션 ACID

트랜잭션은 SQL 쿼리 원자의 집합 또는 작업 별도의 단위입니다.

문장 트랜잭션 개념을 읽을 때, 당신은 여전히 ​​어떤 사업 모르는 것인가? 왜 트랜잭션을 사용합니까? 이것은 트랜잭션 자체가 운전 데이터의 내용 만 이상을 포함하는 매우 복잡한 과정이기 때문이지만, 여기에 포함 된 전체 프로세스 운영 데이터의 내용을 표시합니다. 고전적인 경우에 트랜잭션 살펴보고하기 전에 :

은행의 데이터베이스에 두 개의 테이블이 있다고 가정 : 체크 (확인) 테이블 및 저축 (저축) 테이블. 그녀의 저축 $ 200의 사용자의 당좌 계좌 이체에서 이제 제인은 적어도 세 가지 단계가 필요합니다 계정 :

이상의 $ (200)의 당좌 계좌 잔액을 확인하십시오.

2. 마이너스 당좌 계정 잔액에서 $ (200).

3. 저축에서 $ 200의 증가는 균형을 차지하고있다.

절차 정상적인 상황에 따라,이 세 SQL 문장은이 기능을 달성하기 위해 실행하지만, 동시에 앞의 복수의 사용자가 다음의 가능한 시나리오,이 두 개의 기록 동작 동안에 발생할 수있는 오픈 처리 것을 알게 할 수있다 :

사례 1 : 1 단계와 2 단계에서이 균형을 수정 다른 동시 사용자 프로세스 사이에 설정되어, 상황의 균형이 덜 $ 200 개의 나타납니다, 이번에는 불가피하게 2가 실패 단계로 이어질 것입니다.

사례 2 : 시스템은 2 단계를 실행 한 후 충돌, 3 단계는 달성되지 않으며, 이는 필연적으로 $ 200 사용자 손실로 이어질 것입니다.

케이스 세 : 2 단계를 실행 한 후, 다른 사용자 개방 과정은 $ 200 제인 화이트에 은행을 이끌 수있는 모든 당좌 계좌 잔고를 삭제합니다.

여기에 일시적으로 문제를 해결하는 방법을 특정 데이터베이스 시스템 설명하지 않습니다, 실제 구현이없는 블로그는 이해 할 필요가 없습니다되고, 애플리케이션 개발 단계에서 명확하게 말할 수있을 것입니다, 매우 복잡한 데이터 저장 문제 다음은 이러한 문제의 해결책은 애플리케이션 개발 단계에서 엄격한 기준을 가지고 있기 때문에, 우리는 단지 표준 용액 표준 장면, 어떤 상황에서 어떤 문제가 발생할 수있는 것을 적용 알아야 할, 필요, 따라 사실상의 표준 및 데이터베이스 시스템과 우리가 우리의 데이터베이스를 설계 할 수있는 방법 표준 실현.

트랜잭션에 세 단계의 일반적인 경우는이 세 단계는 엄격한 테스트 ACID를 통해 시스템 않는 한, 정상 수행 완료 할 수 있음을 보증하지 않습니다 트랜잭션을 사용하여 실행됩니다.

ACID : 데이터베이스 트랜잭션의 네 가지 기본 요소가 제대로 각각 수행 수단 (원자 : 원 자성, 일관성 : 일관성, 격리 : 격리, 지속성 : 내구성).

원자는 : 트랜잭션 중 하나를 롤백의 성공 또는 실패를 제출하여 작동 작업 단위입니다, 작업의 일부를 수행하는 것은 불가능합니다. 예를 들어, 케이스의 경우, 2 단계 3 단계로하지 않을 것이다.

일관성 : 다른 일관된 상태의 일관성 한 상태에서 데이터베이스 총 전환. 예를 들어, 2 단계와 3 단계 벤 붕괴의 시스템에 두 개의 케이스의 경우, 체크 계정이 아닌 잃게 $ 200 것이다이 달성되는 방법에 대한, 집행 지점에 제출되지 않습니다에는 3 단계가 없기 때문에, 후자의 내용을 설명합니다.

절연 : 최종 제출하기 전에 메이크업의 변화에 기업은, 다른 트랜잭션이 표시되지 않습니다. 예를 들어, 경우에 2 단계가 완료되었지만 아직 3 단계를 구현되지 않은, 기록 확인 조회 할 다른 사용자 프로세스는 그 기록 쿼리는 마이너스 $ 200 기록되지 않습니다. 그러나 이것은 단지 그것이 나중에 상세하게 설명한다 이론적으로,이 트랜잭션 격리 수준과 관련이 있다고 말할 수있다.

내구성 : 트랜잭션이 커밋되면, 수정 영구적으로 이루어집니다 자신의 데이터베이스에 저장. 심지어 내 시스템 충돌하는 경우, 수정 된 데이터가 손실되지 않습니다. 지속성도 만 상대적으로 말하기, 또는 데이터 백업이며 어떤 의미가 않도록 영구 모든 과정은 많은 수준으로, 일부 지속성 전략은 매우 강력한 데이터 보안을 할 수 있습니다 나누어, 일부는하지 않을 수있다?

 셋째, 트랜잭션 로그

트랜잭션 로그는 원격, 커밋, 롤백, 데이터베이스 스키마 변경 데이터 백업 및 복구의 중요한 구성 요소이며,뿐만 아니라 SQL을 데이터베이스 레코드 파일, 기록 삽입, 업데이트에 대한 변경 사항을 저장 삭제하는 데 사용됩니다 또는 [복사 에이전트] 데이터를 복사 필요.

라고 할 수있다 트랜잭션 로그는 트랜잭션의 기초가 트랜잭션 로그가 무엇인지 결국? 트랜잭션 로그는 어떻게 작업하는 것입니다?

트랜잭션 로그에는 다음이 포함 리두 로그 (리두 로그), 실행 취소 로그 (롤백 로그), 로그 그룹 (로그 그룹).

로그를 다시 실행 : MySQL의 SQL 문을 트랜잭션이 해당 데이터 파일에 다음 리두 로그 작업에 기록 된 로그 및 동기화를 다시 실행하는 작업과 관련된 모든 데이터가 될 것입니다. 데이터베이스 파일에서 레코드를 수정하기 전에 해당되는 모든 수정 작업이 리두 로그에 기록되었는지 확인해야합니다. 리두 로그 버퍼 리두 로그 파일 : 재실행 로그는 두 부분으로 분할된다.

  • 리두 로그 버퍼 (리두 로그 버퍼) : 로그 쓰기 버퍼 메모리, 디스크에 직접 기록하지만 벤은 시스템이 데이터가 손실 될이 시간을 축소하는 경우 메모리가 영구 수요를 충족 할 수없는 것보다 훨씬 빠릅니다.
  • 로그 파일 (리두 로그 파일)을 다시 실행 : 리두 로그 파일이 리두 로그 버퍼에 비해 로그 디스크에 기록하는 것은 매우 느리지 만, 로그가 지속성의 기본 요구 사항을 보장 할 수 디스크에 기록됩니다.

계정에 성능과 내구성을 위해, 일반적으로 작동 IO 메모리 디스크 데이터베이스가 상대적으로 훨씬 느리지 만 상대적 경우에도 첫 번째 트랜잭션 로그 메모리 (리두 로그 버퍼)를 기록한 후 디스크에 동기식 메모리 (리두 로그 파일)을 기록입니다 때문에 리두 로그 파일의 개별 쓰기,하지만 여전히 훨씬 더 빨리는 디스크의 연속 된 공간입니다. 녹음 작업에 로그 파일을 다시 실행하면 데이터베이스 트랜잭션 전체 공정 데이터에 기록되어있는 데이터베이스 파일을 다시 동기화 할 수 있습니다.

리두 로그 파일에 기록 데이터를 리두 로그 버퍼는 데이터 지속성을 보장하기 위해, 그러나 이것은 성능을 크게 줄일 수 있지만 정책에서 innodb_flush_log_at_trx_commit 매개 변수에 의해 리두 로그 버퍼에서 리두 로그 파일을 기록 수정할 수 있지만 그것은 지속을 잃게됩니다 저항, 쓰기 정책, 실제 상황에 따라 장단점을 브러시하기 위해 특별히 방법, 데이터가 손실 될 수 있습니다.

물리적 리두 로그 로그, 검색, 리두 로그 나무 등의 논리적 인 변화를 데이터베이스 리두 로그 페이지 작업 기록 및 삭제하지.

실행 취소 로그 로그 롤링하는 것은 데이터 수정하기 전에 백업으로 이해 될 수 있기 전에, SQL의 성공적인 구현의 어떤 부분이없는 중간을 통해 거래하는 경우, 데이터베이스가 수정 논리적으로 모든 수정 된 데이터를 복원 실행 취소 로그에서 취소 할 수 있습니다 : 업데이트 데이터 (50)에 따라 그들을 업데이트 할 경우 방법, 이러한 데이터 전에 삽입 (100)는, 다음 삭제, 실행 취소 로그 따라서, 실행 취소 로그는 논리 로그 및 물리 페이지 로그 리두 로그의 작업입니다 다른 기록 .

그룹 로그 : 리두 로그 그룹은 여러 리두 로그, 로그 파일이 가득 할 때, 그것은 리두 로그 파일의 다음 그룹의 로그 리두 로그, 로그 그룹의 모든 리두 로그에 기록됩니다 로그 그룹을 포함 파일은, 그래서 새로운 리두 로그 쓰기를 한 후 다시 실행 로그, 작성 후 원래의 리두 로그를 덮어 첫 번째 리두 로그 파일에 기록됩니다. 리두 로그가 다음 로그가 손실됩니다 다시 어디에 장치가 충돌하는 경우, 이것은하지 않습니다 보증 리두 로그는 너무도 지원은 일반적으로 중복 기능과 로그 그룹에 그룹을 미러링 로그 로그 그룹, 항상 볼 수 있습니다 이러한 radi1 같은 장치에서.

리두 로그에 저장 재실행 로그의 취소는 내부 데이터베이스 특별한 세그먼트에 저장된 기록이 세그먼트 테이블 취소 공유 세그먼트에있는 취소 세그먼트 (세그먼트 취소)이라한다. 에 관계없이 리두 로그 또는 데이터베이스를 복구하기 위해 모든 수단을 기록 취소.

MySQL은, 이노 스토리지 엔진을 지원하는 거래에서의 MyISAM 스토리지 엔진은 리두 로그 또는 취소 로그, 모든 InnoDB의 제품에 관계없이 트랜잭션을 지원하지 않지만, 바이너리 로그 또 다른 중요한 MySQL의 바이너리 로그가 존재, 그것은 시간의 MySQL입니다 로그에 필요한 마스터 - 슬레이브 복제 환경,하지만 스토리지 엔진 수준의 바이너리 로그 로그는 MySQL 데이터베이스 스토리지 엔진은 바이너리 로그 데이터베이스에 변경 사항을 생성합니다.

디스크가 다른에 거래 만 트랜잭션 커밋 완료 후, 바이너리 로그 회전 디스크 쓰기를 수행 할 때 리두 로그 리두 로그 파일을 작성 계속 이노, 바이너리 로그 타이밍 및 쓰기를 리두 로그.

보기 이노 디비 스토리지 엔진 로그 구성 매개 변수 :

보여 글로벌 과 같은 변수 ' % 이노 % 로그 %를 '

: 특정 매개 변수 설명 로그는이 블로그를 참조 할 수 있습니다 http://www.zsythink.net/archives/1216 : 또한 공식 문서를 참조 할 수 있습니다에 대한 자세한 정보를 https://dev.mysql.com/doc/refman/5.7/ EN / 이노 저장-engine.html

 넷째, 트랜잭션 격리 수준

원자 트랜잭션, 지속성을 기록 이미 배운 트랜잭션에 해결 될 수있는 상황 ACID는 필수 요소 (격리) 왼쪽 포함되어 있지 않은 경우, 분리는 무엇인가? 왜 우리는 분리, 차이점은 무엇입니까 분리 레벨을 필요합니까?

다른 트랜잭션 작업이 분리되어 내부 트랜잭션 격리 뭔가를 말합니다 서로 동시에 실행되는 여러 가지 방해 할 수 없습니다.

  • READ UNCOMMITTED (커밋되지 않은 읽기)
  • READ 커밋 (커밋 읽기)
  • REPEATABLE READ (반복 읽기)
  • SERIALIZABLE (직렬화)

 4.1 : READ UNCOMMITTED (커밋되지 않은 읽기)

커밋되지 않은 트랜잭션이 트랜잭션이 커밋되지 않은 경우에도 데이터의 수정을 나타내는 읽기, 다른 트랜잭션도 볼 수 있습니다. 사용자 데이터 연산 프로세스가 다른 사용자 프로세스 열린 트랜잭션 B 동안, 트랜잭션이 데이터 수정 문을 실행, 업무을 시작했다고 가정합시다 있지만, 트랜잭션이 제출되지 않은, B의 트랜잭션은 즉시 단지 트랜잭션을 읽을 수정을 수행했다 읽기 UNCOMMITTED 격리 수준의 데이터는 수정 된 트랜잭션 데이터입니다 데이터를 읽습니다.

거의 사용하지 정말 필요한 경우가 아니면 READ UNCOMMITTED의 성능을 가리 키지 훨씬 더 이외의 수준,하지만에서 다른 레벨의 혜택을 많이 부족하다.

더러운 읽기 SQL 데이터 수정 문을 실행 다른 트랜잭션을 읽는 것을 의미하지 않는다,하지만 거래 데이터가 발생합니다 제출하지 않았지만, 데이터를 읽는 대신 할 때 수행 할 수 있지만, 트랜잭션 롤백의 발생에 의해 제출 된 데이터를 수정하지 않았다 때문에 어떤 더러운 만 알려진 읽을 때 더러운가 일치하지 않는 데이터를 읽고 사건의 데이터베이스에 기록 읽기에, 사실을 의미한다.

4.2 : READ 커밋 (커밋 읽기)

트랜잭션이 시작되면, 우리는 보이지 않는 다른 트랜잭션에 제출하기 전에 회사가 어떤 회사가 수행하는 것으로, 변경 사항이 제출 한했다 "볼"수 있습니다. 이 레벨은 때때로 서로 다른 결과를 얻을 수 있으며, 동일한 쿼리 내정 때문에 두 번 반복 불가능한 읽기라고합니다.

4.3 : REPEATABLE READ (반복 읽기)

동일한 트랜잭션을 여러 번 같은 레코드 구조를 읽을 수있는 것이이 수준 보장하지만은 동일하지만, 이론적으로, 반복 읽기 분리 레벨은 또 다른 문제 팬텀 읽기가 해결되지 않습니다.

매직 읽기 : 트랜잭션이 읽기, 다른 트랜잭션의 범위 및 거래 전에 레코드 범위를 다시 읽을 때, 그것은 팬텀 라인을 생산할 예정이 범위에서 새 레코드 삽입 기록 될 때 (팬텀 행) . XtraDB 및 이노 스토리지 엔진은 팬텀의 문제가 다중 버전 동시성 제어 (MVCC, 다중 버전 동시성 제어)에 의해 판독 해결.

반복 읽기의 MySQL의 기본 격리 수준 일이다.

4.4 : SERIALIZABLE (직렬화)

직렬화 격리 수준은 최고입니다. 그것은 일을 강제로 직렬 실행, 팬텀 읽기의 문제를 방지 이전했다. 간단히 말해, SERIALIZABLE는 시간 초과 및 잠금 경합의 많은 문제가 발생할 수 있습니다, 읽을 데이터의 각 행에 대한 잠금을해야합니다. 실제 응용 프로그램은 거의 데이터의 일관성을 보장하기 위해 매우 필요에서,이 격리 수준을 사용하지 않고 동시 사건을 받아 들일 수 없습니다 만 그 수준은 고려하십시오.

---------------------------------------

ANSI SQL 격리 수준 :

 V. 교착 상태

교착 상태는 두 개 이상의 가지가 동일한 자원을 서로 차지을 의미하며, 다른 점유 자원 잠금 요청, 악순환 현상에 선도. 많은 일들이 다른 순서로 자원을 고정하면 교착 상태가 발생할 수 있습니다. 여러 트랜잭션이 동시에 동일한 자원을 고정 할 때, 교착 상태를 생성한다. 다음 예와 같은 :

거래 1 :

start transaction ;
update t_employee set sal=5000 where ename='JONES';
update t_employee set sal=4500 where ename='BLAKE';
commit ;

事务2:

start transaction ;
update t_employee set sal=6000 where ename='BLAKE';
update t_employee set sal=3800 where ename='JONES';
commit ;

可以尝试启动两个控制台进入数据库然后按照以下顺序执行语句:

 执行到第三步时,两个进程都会等待一会儿,然后报超时错误:

ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

为了解决死锁的问题,数据库系统实现了各种死锁检测和死锁超时机制。越复杂的系统比如InnoDB存储引擎,越能检测到死锁的循环依赖,并立即返回一个错误。除了这种解决方法以外就是当查询达到锁超时的设定后放弃锁请求,这种方式不太友好。InnoDB目前处理死锁的方法是,将有最少行级排他锁的事务进行回滚。

锁的行为和顺序是和存储引擎相关的,以同样的顺序执行语句,有些存储引擎会产生死锁,有些则不会。死锁产生有双重原因:有些是因为真正的数据冲突,这种情况通常很难避免,但有些则完全是由于存储引擎的实现方式导致。

上面示例测试的表事务隔离级是REPEATABLE READ,存储引擎是InnoDB。

 

 关于死锁更详细的解析和解决方案可以参考这篇博客:https://blog.csdn.net/qq_36132127/article/details/81272293

 六、MVCC

MVCC全称Multi-Version Concurrency Control,即多版本并发控制协议。MySQL的大多数事务型存储引擎都不是简单的行级锁,为了提升并发性能的,它们一般都同时实现了并发控制。而且不仅仅是MySQL,包括Oracle、PostgreSQL等其他数据库系统也都实现了MVCC,但各自的实现机制不尽相同,因为MVCC没有统一的实现标准。

MVCC很多情况下避免了枷锁操作,因此开销更低。虽然实现机制不同,但大都实现了非阻塞的读操作。写也只锁定必要的行。MVCC是通过保存数据在某个时间点的快照来实现,不管一个事务要执行多长时间,事务内部每个时间点看到的数据都是一致的。

前面说过MVCC在不同存储引擎实现是不同的,典型的有乐观(optimistic)并发控制和悲观(pessimistic)并发控制。

InnoDB的MVCC是通过在每行记录后面保存两个隐藏的列来实现的,这两个列分别保存行的创建时间和过期时间(或称为“删除时间”)。而且存储并不是实际时间值,而是系统版本号(system version number)。下面来看看InnoDB的SQL操实际是如何来操作这两个隐藏列的:

INSERT :为新插入的每一行保存当前系统版本号作为行的版本号。

DELETE:为删除的每一行保存当前系统版本号作为行的删除标示。

UPDATE:插入一行新的记录,保存当前系统版本号作为行的版本号,同时保存当前系统版本号到原来的行作为删除标识。(也就是说修改数据实际上是新增一行记录,删除原来的记录)。

SELECT:查找版本早于或等于当前事务版本号的数据行,并且删除把呢不能还未定义。意思就是查找早于当前事务版本的记录,这是在事务内部未对查找的记录删除或修改;如果在查询前当前事务新增的记录是可以被查询到的,在查询前事务内部修改的记录也是可以查询到的,查询前事务内部的删除也可以被查看到。

根据上面的说明,也就是说可重复读并不意味着在事物内部两次相同的读语句可以完全获得相同的结果。

 六、MySQL的事务

在MySQL中默认情况下,每一条SQL语句都当作一个单语句事务,并默认自动提交,可以通过下列语句查看全局和当前会话是否开启自动提交功能。

show global variables like 'autocommit%';
show session variables like 'autocommit%';

并且可以手动关闭当前会话的默认提交:

set autocommit=0;

如果手动关闭了默认提交,执行SQL数据操作语句后就需要手动使用commit提交。

 

 除了默认SQL语句自动默认采用事务机制,可以通过手动开启事务并提交,下面是MySQL事务控制语句的语法:

START TRANSACTION | BEGIN [work]
COMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
ROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE]

START TRANSACTION 或BEGIN:表示开启一个事务。当由于在存储过程中BEGIN END作为SQL语句的包裹关键字,所以为了区分一般使用START TRANSACTION作为事务开启语句。

COMMIT或COMMIT WORK:表示提交事务。也就是说START TRANSACTION 与COMMIT之间的SQL语句对数据的操作称为永久性操作。

ROLLBACK或ROLLBACK WORK:表示事务回滚。也就是撤销事务中在回滚语句之前的数据操作,之后的数据不会被撤销,这一点需要注意。

除了以上三个语句以外,还可以使用标识符用来控制回滚。

SAVEPOINT #表示创建标识符
ROLLBACK TO SAVEPOINT#表示回滚到这个标识符的记录
RELEASE SAVEPOINT #表示删除一个保存点

本来想着写一个示例,但是在感觉没有这个必要了,如果需要的话可以参考下面这两篇博客:

http:/www.zsythink.net/archives/1216

https://www.cnblogs.com/Yiran583/p/7125455.html

추천

출처www.cnblogs.com/ZheOneAndOnly/p/12148946.html