MySQL 의 격 리 단 계 를 전면적으로 분석 합 니 다.
사 무 는 SQL 로 구 성 된 논리 처리 장치 입 니 다.먼저 업무 의 ACID 특성 을 살 펴 보 겠 습 니 다.
격 리 단계
더러 운 읽 기(더러 운 읽 기)
중복 읽 기 불가(반복 읽 기 불가)
환 독(Phantom Read)
읽 기 미 제출(읽 기 uncommitted)
이 가능 하 다,~할 수 있다,...
이 가능 하 다,~할 수 있다,...
이 가능 하 다,~할 수 있다,...
제출 한 읽 기(읽 기 committed)
불가능
이 가능 하 다,~할 수 있다,...
이 가능 하 다,~할 수 있다,...
반복 읽 기 가능(반복 읽 기)
불가능
불가능
이 가능 하 다,~할 수 있다,...
직렬 화(Serializable)
불가능
불가능
불가능
MySQL 은 위의 네 가지 격 리 단 계 를 제공 하 는데 격 리 가 엄격 할 수록 발생 할 수 있 는 문제 가 적 지만 지불 하 는 성능 대가 가 클 수록 기본 격 리 단 계 는 중복 읽 을 수 있다.다음은 클 라 이언 트 를 사용 하여 조작 을 검증 합 니 다.
먼저 표 와 데 이 터 를 만 듭 니 다.
CREATE TABLE `account` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`balance` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `account` (`id`, `balance`)
VALUES
(1, 500),
(2, 600),
(3, 200);
클 라 이언 트 를 연결 하고 격 리 단 계 를 보면 중복 읽 을 수 있 습 니 다.
MySQL [test]> show variables like 'tx_isolation';
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| tx_isolation | REPEATABLE-READ |
+---------------+-----------------+
읽 기 미 제출 테스트:AB 클 라 이언 트 모두 set tx 실행isolation='read-uncommitted';읽 기 미 제출 로 격 리 단 계 를 설정 합 니 다.
A 클 라 이언 트 가 업 무 를 시작 합 니 다:start transaction;조회 데이터:select*from account;
B 클 라 이언 트 오픈 사무:start transaction;업데이트 데이터:update account set balance=balance-100 where id=1;이 때 트 랜 잭 션 이 제출 되 지 않 았 습 니 다.
클 라 이언 트 가 데 이 터 를 다시 조회:select*from account;이때 두 번 조회 한 데 이 터 는 이미 달 라 졌 다.
B 가 제출 하기 전에 A 는 B 가 업데이트 한 데 이 터 를 읽 었 습 니 다.이때 B 가 굴 러 가면 A 쪽 은 더러 운 데이터 입 니 다.이런 상황 은 제출 되 지 않 은 더러 운 독 서 를 읽 는 것 이다.읽 기 제출 한 격 리 단계 로 해결 할 수 있 습 니 다.
commt 명령 을 사용 하여 AB 클 라 이언 트 의 업 무 를 제출 합 니 다.
제출 한 테스트 읽 기:
AB 클 라 이언 트 모두 실행 set tx_isolation='read-committed'; 읽 기 제출 을 위 한 격 리 단 계 를 설정 합 니 다.
A 클 라 이언 트 가 업 무 를 시작 합 니 다:start transaction;조회 데이터:select*from account;
B 클 라 이언 트 오픈 사무:start transaction;업데이트 데이터:update account set balance=balance-100 where id=1;이 때 트 랜 잭 션 이 제출 되 지 않 았 습 니 다.
클 라 이언 트 가 데 이 터 를 다시 조회:select*from account; 이때 A 클 라 이언 트 가 두 번 조회 한 데이터 가 일치 하고 더러 운 읽 기 상황 이 나타 나 지 않 는 것 을 보 았 습 니 다.
이때 B 클 라 이언 트 업무 제출:commt;
클 라 이언 트 가 데 이 터 를 다시 조회:select*from account;이때 A 클 라 이언 트 조회 데이터 가 변 한 것 을 보 았 습 니 다.이것 은 중복 읽 을 수 없 는 것 입 니 다.
반복 읽 기 테스트:
AB 클 라 이언 트 모두 실행 set tx_isolation='repeatable-read'; 중복 읽 을 수 있 도록 격 리 단 계 를 설정 합 니 다.
A 클 라 이언 트 가 업 무 를 시작 합 니 다:start transaction;조회 데이터:select*from account;
B 클 라 이언 트 오픈 사무:start transaction;업데이트 데이터:update account set balance=balance-100 where id=1;commt 제출 사무
클 라 이언 트 가 데 이 터 를 다시 조회:select*from account; 이때 A 클 라 이언 트 가 두 번 조회 한 데이터 가 일치 하고 중복 읽 기 데이터 가 일치 하 는 것 을 보 았 습 니 다.
A 클 라 이언 트 실행 업데이트 문구:update account set balance=balance-50 where id=1;
클 라 이언 트 가 데 이 터 를 다시 조회:select*from account;이때 id=1 의 이 데 이 터 는 B 클 라 이언 트 가 업데이트 한 데이터-50 이 고 데이터 의 일치 성 은 파괴 되 지 않 았 습 니 다.
B 클 라 이언 트 가 업 무 를 다시 시작 하고 데 이 터 를 삽입 합 니 다.insert into account(id,balance)values(4,1000);commt 제출 사무;
A 클 라 이언 트 조회,지난번 결과 와 일치
A 클 라 이언 트 실행:update account set balance=balance-100 where id=4;B 클 라 이언 트 가 새로 삽입 한 데 이 터 를 업데이트 하면 성공 적 으로 실행 할 수 있 고 모든 데 이 터 를 다시 조회 할 수 있 으 며 id=4 의 데 이 터 를 삽입 하여 환 독 할 수 있 습 니 다.
# A :# MySQL [test]> set tx_isolation='repeatable-read';
Query OK, 0 rows affected, 1 warning (0.00 sec)
#
MySQL [test]> start transaction;
Query OK, 0 rows affected (0.00 sec)
#
MySQL [test]> select * from account;
+----+---------+
| id | balance |
+----+---------+
| 1 | 300 |
| 2 | 600 |
| 3 | 200 |
+----+---------+
3 rows in set (0.00 sec)
#
MySQL [test]> select * from account;
+----+---------+
| id | balance |
+----+---------+
| 1 | 300 |
| 2 | 600 |
| 3 | 200 |
+----+---------+
3 rows in set (0.00 sec)
# B , A
MySQL [test]> select * from account;
+----+---------+
| id | balance |
+----+---------+
| 1 | 150 |
| 2 | 600 |
| 3 | 200 |
+----+---------+
3 rows in set (0.00 sec)
# A B ,
MySQL [test]> update account set balance = balance + 1000 where id = 4;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
# , ,
MySQL [test]> select * from account;
+----+---------+
| id | balance |
+----+---------+
| 1 | 400 |
| 2 | 600 |
| 3 | 200 |
| 4 | 2000 |
+----+---------+
4 rows in set (0.00 sec)
#
MySQL [test]> commit;
Query OK, 0 rows affected (0.01 sec)
# B :
MySQL [test]> set tx_isolation='repeatable-read';
Query OK, 0 rows affected, 1 warning (0.00 sec)
#
MySQL [test]> start transaction;
Query OK, 0 rows affected (0.00 sec)
# ,
MySQL [test]> update account set balance = balance - 100 where id = 1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
MySQL [test]> commit;
Query OK, 0 rows affected (0.01 sec)
#
MySQL [test]> start transaction;
Query OK, 0 rows affected (0.00 sec)
#
MySQL [test]> insert into account(id,balance) values (4,1000);
Query OK, 1 row affected (0.01 sec)
MySQL [test]> commit;
Query OK, 0 rows affected (0.00 sec)
마지막 직렬 화:set txisolation='serializable';자체 적 으로 검증 할 수 있 고 위의 모든 문 제 를 해결 할 수 있 지만 일반적으로 사용 되 지 않 습 니 다.일치 성 을 확보 하 는 동시에 성능 이 큰 폭 으로 떨 어 지고 동시성 이 매우 낮 으 며 기본 적 으로 중복 읽 을 수 있 습 니 다.격 리 단 계 를 통 해 어느 정도 에 업무 병행 문 제 를 처리 할 수 있 고 그 밖 에 다른 수단 이 있 으 므 로 추 후 다시 탐구 할 것 이다.
이상 은 MySQL 의 격 리 단 계 를 전면적으로 분석 하 는 상세 한 내용 입 니 다.MySQL 격 리 단계 에 관 한 자 료 는 다른 관련 글 을 주목 하 십시오!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Redash를 사용할 때 몰랐던 SQL을 쓰는 법을 배웠습니다.최근 redash에서 sql을 쓸 기회가 많고, 이런 쓰는 방법이 있었는지와 sql에 대해 공부를 다시하고 있기 때문에 배운 것을 여기에 씁니다. Redash란? 월별로 데이터를 표시하고 싶습니다 주별로 데이터를 표...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.