> 데이터 베이스 > MySQL 튜토리얼 > MySQL의 트랜잭션 및 MVCC 원리를 자세히 설명하는 기사

MySQL의 트랜잭션 및 MVCC 원리를 자세히 설명하는 기사

青灯夜游
풀어 주다: 2022-03-09 11:05:01
앞으로
2574명이 탐색했습니다.

이 기사는 MySQL의 트랜잭션을 이해하고 MVCC의 원리를 소개하는 데 도움이 되기를 바랍니다.

MySQL의 트랜잭션 및 MVCC 원리를 자세히 설명하는 기사

01 거래란 무엇인가요?

데이터베이스 트랜잭션은 일련의 데이터 작업을 의미합니다. 트랜잭션 내의 작업은 모두 성공하거나 모두 실패합니다. 실제로 아무것도 수행되지 않을 수도 있습니다. 모든 작업을 롤백하는 것은 아무것도 하지 않고 아무 것도 하지 않는 것과 비슷합니다.

MySQL에서는 트랜잭션 지원이 엔진 레이어에서 구현됩니다. MySQL은 여러 엔진을 지원하는 시스템이지만 모든 엔진이 트랜잭션을 지원하는 것은 아닙니다. 예를 들어, MySQL의 기본 MyISAM 엔진은 트랜잭션을 지원하지 않습니다. 이는 MyISAM이 InnoDB로 대체된 중요한 이유 중 하나입니다.

1.1 네 가지 주요 특징

  • 원자성: 트랜잭션이 시작된 후 모든 작업이 완료되거나 완료되지 않으며 중간에 정체가 불가능합니다. 트랜잭션 실행 중 오류가 발생하면 트랜잭션이 시작되기 전 상태로 롤백되어 모든 작업이 발생하지 않은 것처럼 처리됩니다. 즉, 물질의 기본 단위인 화학에서 배운 원자와 마찬가지로 사물은 분할할 수 없는 전체입니다.
  • 일관성: 트랜잭션 시작 전후에 데이터베이스의 무결성 제약 조건을 위반하지 않습니다. 예를 들어, A가 B에게 돈을 이체할 때 A는 돈을 공제할 수 있지만 B는 돈을 받지 못할 수 있습니다.
  • 격리: 하나의 트랜잭션만 동시에 동일한 데이터를 요청할 수 있으며 서로 다른 트랜잭션 간에 간섭이 없습니다. 예를 들어, A는 은행 카드에서 돈을 인출하고 있습니다. B는 A의 인출 절차가 완료되기 전에는 이 카드로 돈을 이체할 수 없습니다.
  • 내구성: 트랜잭션이 완료된 후 트랜잭션으로 인해 데이터베이스에 대한 모든 업데이트가 데이터베이스에 저장되며 롤백할 수 없습니다.

1.2 격리 수준

SQL 트랜잭션의 네 가지 특성 중 원자성, 일관성, 내구성은 모두 비교적 이해하기 쉽습니다. 하지만 트랜잭션의 격리 수준은 실제로 어렵습니다. 오늘은 주로 MySQL 트랜잭션의 격리에 대해 이야기하겠습니다.

SQL 표준 트랜잭션 격리 수준은 낮음부터 높음까지 커밋되지 않은 읽기(커밋되지 않은 읽기), 커밋된 읽기(커밋된 읽기), 반복 가능한 읽기(반복 가능한 읽기) 및 직렬화 가능(직렬화 가능)입니다. 레벨이 높을수록 효율성은 낮아집니다.

  • 커밋되지 않은 읽기: 트랜잭션이 커밋되지 않은 경우 해당 변경 사항을 다른 트랜잭션에서 볼 수 있습니다.
  • 커밋 읽기: 트랜잭션이 커밋된 후 변경 사항이 다른 트랜잭션에 표시됩니다.
  • 반복 읽기: 트랜잭션 실행 중에 표시되는 데이터는 트랜잭션이 시작될 때 표시되는 데이터와 항상 일치합니다. 물론 반복 가능한 읽기 격리 수준에서는 커밋되지 않은 변경 사항도 다른 트랜잭션에서 볼 수 없습니다.
  • 직렬화: 이름에서 알 수 있듯이 동일한 레코드 행에 대해 "쓰기"는 "쓰기 잠금"을 추가하고 "읽기"는 "읽기 잠금"을 추가합니다. 읽기-쓰기 잠금 충돌이 발생하면 나중에 액세스되는 트랜잭션은 계속 실행되기 전에 이전 트랜잭션이 완료될 때까지 기다려야 합니다. 그래서 이 격리 수준 아래의 모든 데이터는 가장 안정적이지만 성능도 최악입니다.

1.3 동시성 문제 해결

SQL 트랜잭션 격리 수준은 동시성 문제를 최대한 해결하도록 설계되었습니다.

  • Dirty 읽기: 트랜잭션 A가 트랜잭션 B에 의해 업데이트된 데이터를 읽은 다음 B가 Roll 작업을 반환합니다. , 그러면 A가 읽은 데이터는 더티 데이터입니다
  • 비반복 읽기: 트랜잭션 A는 동일한 데이터를 여러 번 읽고, 트랜잭션 B는 트랜잭션 A를 여러 번 읽는 동안 데이터를 업데이트하고 커밋합니다. 결과적으로 트랜잭션 A가 동일한 데이터를 읽을 때 데이터를 여러 번 사용하면 결과가 일치하지 않습니다.
  • 팬텀 리딩: 시스템 관리자 A가 데이터베이스 내 모든 학생의 성적을 특정 점수에서 ABCDE 등급으로 변경했는데 시스템 관리자 B가 이때 특정 점수의 기록을 삽입한 결과 시스템 관리자 A가 변경을 완료한 것을 발견했습니다. 마치 환각이 일어난 것처럼 변하지 않은 또 다른 기록을 유령읽기라고 합니다.

다음 표에 표시된 것처럼 다양한 SQL 트랜잭션 격리 수준은 다양한 동시성 문제를 해결할 수 있습니다. 직렬화 격리 수준만이 세 가지 문제를 모두 해결하고 나머지 세 가지 격리 수준에는 결함이 있습니다.

트랜잭션 격리 수준 더티 읽기 반복 불가능한 읽기 팬텀 읽기
커밋되지 않은 읽기 Possible Possible 가능
읽음 제출됨 불가능 가능 가능
반복읽기 불가능 불가능 가능
직렬화 불가능 불가능 불가능

PS: 비반복 읽기와 팬텀 읽기를 혼동하기 쉽습니다. 비반복 읽기는 수정에 중점을 두고, 팬텀 읽기는 추가 또는 삭제에 중점을 둡니다. 반복되지 않는 읽기 문제를 해결하려면 조건에 맞는 행만 잠그면 됩니다. 환상 읽기 문제를 해결하려면 테이블을 잠그면 됩니다

1.4 예를 들어보세요

이것입니다. 조금 이해하기 어려울 수도 있습니다. 예를 들어 보겠습니다. 테이블 구조와 테이블 데이터는 여전히 동일합니다

CREATE TABLE `student`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `age` int(11) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 66 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
로그인 후 복사

MySQL의 트랜잭션 및 MVCC 원리를 자세히 설명하는 기사

이제 동시에 두 가지 음식을 시작하려고 한다고 가정해 보겠습니다. 트랜잭션 A는 ID = 2로 학생의 나이를 쿼리하고 트랜잭션 B는 업데이트합니다. ID = 2 인 학생의 나이. 4가지 격리 수준에서 X1, X2, X3의 값은 무엇인가요?

MySQL의 트랜잭션 및 MVCC 원리를 자세히 설명하는 기사

  • 커밋되지 않은 읽기: X1의 값은 23입니다. 트랜잭션 B가 커밋되지 않았지만 해당 변경 사항이 A에서 확인되었기 때문입니다. (B가 나중에 X1의 값을 롤백하면 더티). X2와 X3의 값도 23으로 이해가 됩니다.
  • 제출된 읽기: B가 변경되었지만 A는 이를 볼 수 없기 때문에 X1의 값은 22입니다. (B가 나중에 롤백되면 X1의 값은 변경되지 않고 그대로 유지되므로 더티 읽기 문제가 해결됩니다).
  • 반복 읽기: X1 및 (이 기간 동안 B를 어떻게 수정하더라도 A가 제출하지 않는 한 보이지 않으므로 반복 읽기 불가 문제가 해결됩니다), A가 제출했으므로 X3의 값은 23입니다. B의 수정된 값을 볼 수 있습니다.
  • 직렬화: A가 커밋할 때까지 변경을 수행하는 동안 B는 잠깁니다. B는 실행을 계속할 수 있습니다. (A가 읽는 동안 B는 쓸 수 없습니다. 이때 데이터가 최신인지 확인해야 합니다. 팬텀 읽기가 해결됩니다) 따라서 X1과 X2는 모두 22이고 B가 제출된 후 최종 X3가 실행되며, 그 값은 23입니다.

그렇다면 왜 이런 결과가 나오는 걸까요? 트랜잭션 격리 수준은 어떻게 구현됩니까?

거래 격리 수준은 어떻게 구현되나요? 저는 Geek Time의 Ding Qi 선생님 수업에서 답을 찾았습니다.

사실 데이터베이스에 뷰가 생성되고, 액세스할 때 뷰의 논리적 결과가 우선합니다. "반복 읽기" 격리 수준에서 이 뷰는 트랜잭션이 시작될 때 생성되고 트랜잭션 전체에서 사용됩니다. "읽기 커밋" 격리 수준에서 이 뷰는 각 SQL 문의 시작 부분에 생성됩니다. 여기서 주목해야 할 점은 "커밋되지 않은 읽기" 격리 수준에서는 뷰 개념 없이 레코드의 최신 값이 직접 반환되는 반면, "직렬화" 격리 수준에서는 병렬을 피하기 위해 잠금이 직접 사용된다는 것입니다. 접속.

1.5 트랜잭션 격리 수준 설정

다양한 데이터베이스에 의해 설정되는 기본 트랜잭션 격리 수준도 매우 다릅니다. Oracle 데이터베이스의 기본 격리 수준은 읽기 커밋인 반면 MySQL은 반복 읽기입니다. 따라서 시스템이 Oracle에서 MySQL로 데이터베이스를 마이그레이션해야 하는 경우 예측할 수 없는 문제를 방지하기 위해 마이그레이션(읽기-커밋) 전과 일치하도록 레벨을 설정하십시오.

1.5.1 트랜잭션 격리 수준 보기

# 查看事务隔离级别
5.7.20 之前
SELECT @@transaction_isolation
show variables like 'transaction_isolation';

# 5.7.20 以及之后
SELECT @@tx_isolation
show variables like 'tx_isolation'

+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| tx_isolation  | REPEATABLE-READ |
+---------------+-----------------+
로그인 후 복사

1.5.2 격리 수준 설정

격리 수준 수정을 위한 문 형식은 다음과 같습니다. level]

범위는 선택 사항입니다: SESSION(세션), GLOBAL(전역); 격리 수준은 위에서 언급한 네 가지이며 대소문자를 구분하지 않습니다.

예: 전역 격리 수준을 커밋된 읽기로 설정

set global transaction isolation level read committed;
로그인 후 복사

1.6 트랜잭션 시작

MySQL 트랜잭션은 다음과 같은 방법으로 시작할 수 있습니다.

  • 显式启动事务语句, begin 或 start transaction。配套的提交语句是 commit,或者回滚语句是 rollback。
# 更新学生名字
START TRANSACTION;
update student set name = '张三' where id = 2;
commit;
로그인 후 복사
  • set autocommit = 0,这个命令会将线程的自动提交关掉。意味着如果你只执行一个 select 语句,这个事务就启动了,而且并不会自动提交。这个事务持续存在直到你主动执行 commit 或 rollback 语句,或者断开连接。
  • set autocommit = 1,表示 MySQL 自动开启和提交事务。 比如执行一个 update 语句,语句只完成后就自动提交了。不需要显示的使用 begin、commit 来开启和提交事务。所以当我们执行多个语句的时候,就需要手动的用 begin、commit 来开启和提交事务。
  • start transaction with consistent snapshot;上面提到的 begin/start transaction 命令并不是一个事务的起点,在执行到它们之后的第一个操作 InnoDB 表的语句,事务才真正启动。如果你想要马上启动一个事务,可以使用 start transaction with consistent snapshot 命令。 第一种启动方式,一致性视图是在执行第一个快照读语句时创建的; 第二种启动方式,一致性视图是在执行 start transaction with consistent snapshot 时创建的

02 事务隔离的实现

理解了隔离级别,那事务的隔离是怎么实现的呢?要想理解事务隔离,先得了解 MVCC 多版本的并发控制这个概念。而 MVCC 又依赖于 undo log 和 read view 实现。

2.1 什么是 MVCC?

百度上的解释是这样的:

MVCC,全称 Multi-Version Concurrency Control,即多版本并发控制。MVCC 是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问,在编程语言中实现事务内存。

MVCC 使得数据库读不会对数据加锁,普通的 SELECT 请求不会加锁,提高了数据库的并发处理能力;数据库写才会加锁。 借助 MVCC,数据库可以实现 READ COMMITTED,REPEATABLE READ 等隔离级别,用户可以查看当前数据的前一个或者前几个历史版本,保证了 ACID 中的 I 特性(隔离性)。

MVCC 只在 REPEATABLE READ 和 READ COMMITIED 两个隔离级别下工作。其他两个隔离级别都和 MVCC 不兼容 ,因为 READ UNCOMMITIED 总是读取最新的数据行,而不是符合当前事务版本的数据行。而 SERIALIZABLE 则会对所有读取的行都加锁。

2.1.1 InnDB 中的 MVCC

InnDB 中每个事务都有一个唯一的事务 ID,记为 transaction_id。它在事务开始时向 InnDB 申请,按照时间先后严格递增。

而每行数据其实都有多个版本,这就依赖 undo log 来实现了。每次事务更新数据就会生成一个新的数据版本,并把  transaction_id 记为 row trx_id。同时旧的数据版本会保留在 undo log 中,而且新的版本会记录旧版本的回滚指针,通过它直接拿到上一个版本。

所以,InnDB 中的 MVCC 其实是通过在每行记录后面保存两个隐藏的列来实现的。一列是事务 ID:trx_id;另一列是回滚指针:roll_pt。

2.2 undo log

回滚日志保存了事务发生之前的数据的一个版本,可以用于回滚,同时可以提供多版本并发控制下的读(MVCC),也即非锁定读。

根据操作的不同,undo log 分为两种: insert undo log 和 update undo log。

2.2.1 insert undo log

insert 操作产生的 undo log,因为 insert 操作记录没有历史版本只对当前事务本身可见,对于其他事务此记录不可见,所以 insert undo log 可以在事务提交后直接删除而不需要进行 purge 操作。

purge 的主要任务是将数据库中已经 mark del 的数据删除,另外也会批量回收 undo pages

所以,插入数据时。它的初始状态是这样的:

insert undo log

2.2.2 update undo log

UPDATE 和 DELETE 操作产生的 Undo log 都属于同一类型:update_undo。(update 可以视为 insert 新数据到原位置,delete 旧数据,undo log 暂时保留旧数据)。

事务提交时放到 history list 上,没有事务要用到这些回滚日志,即系统中没有比这个回滚日志更早的版本时,purge 线程将进行最后的删除操作。

한 트랜잭션이 현재 데이터를 수정합니다.

MySQL의 트랜잭션 및 MVCC 원리를 자세히 설명하는 기사

또 다른 트랜잭션이 데이터를 수정합니다.

MySQL의 트랜잭션 및 MVCC 원리를 자세히 설명하는 기사

데이터베이스에 동일한 레코드의 여러 버전이 있는데, 이는 다중 버전 동시성 제어 MVCC에서 언급된 것입니다. 위에 .

또한 실행 취소 로그를 사용하여 이전 버전 상태로 롤백할 수 있습니다. 예를 들어 V1으로 돌아가려면 두 번의 롤백만 순차적으로 수행하면 됩니다.

2.3 read-view

read view는 RC(Read Commit) 및 RR(Repeatable Read) 격리 수준 구현을 지원하기 위해 MVCC를 구현할 때 InnDB에서 사용하는 일관된 읽기 뷰입니다.

읽기 보기는 실제로 존재하지 않으며 단지 개념일 뿐이며 실행 취소 로그는 이를 구체화한 것입니다. 주로 버전과 로그 취소를 통해 계산됩니다. 그 기능은 거래가 볼 수 있는 데이터를 결정하는 것입니다.

각 거래 또는 명세서에는 고유한 일관성 보기가 있습니다. 일반적인 쿼리 문은 일관된 읽기입니다. 일관된 읽기는 행 trx_id 및 일관된 보기를 기반으로 데이터 버전의 가시성을 결정합니다.

2.3.1 데이터 버전의 가시성 규칙

읽기 뷰에는 주로 현재 시스템의 다른 활성 읽기 및 쓰기 트랜잭션이 포함됩니다. 구현 시 InnDB는 이 트랜잭션이 시작되는 순간 저장하기 위해 각 트랜잭션에 대한 배열을 구성합니다. 현재 활성(아직 제출되지 않은) 거래입니다. 앞서 언급했듯이 트랜잭션 ID는 시간이 지남에 따라 엄격하게 증가합니다.

시스템에 제출된 트랜잭션 ID의 최대 값은 배열의 저수위로 기록되고, 생성된 트랜잭션 ID + 1은 최고 수위로 기록됩니다. 레벨

.

이 뷰 배열과 높은 수위는 현재 트랜잭션의 일관성 뷰(읽기 뷰)를 형성합니다.

이 배열의 그림을 그리세요. 다음과 같습니다.

MySQL의 트랜잭션 및 MVCC 원리를 자세히 설명하는 기사규칙은 다음과 같습니다. :

1 trx_id인 경우 회색 영역에서는 액세스한 버전의 trx_id가 배열의 저수위 id 값보다 작다는 것을 나타냅니다. 즉, 이 버전을 생성한 트랜잭션이 생성 전에 커밋되었음을 나타냅니다. 읽기 보기이므로 이 버전이 표시되고 현재 트랜잭션에서 액세스할 수 있습니다.
  • 2 trx_id가 주황색 영역에 있으면 액세스한 버전의 trx_id가 배열의 최고 수위에 대한 id 값보다 크다는 의미입니다. 즉, 이 버전을 생성한 트랜잭션이 읽기 보기 이후에 생성되었음을 의미합니다. 생성되었으므로 이 버전은 표시되지 않으며 현재 트랜잭션에서 액세스할 수 없습니다.
  • 3 녹색 영역에 있으면 두 가지 상황이 발생합니다.
  • a) trx_id가 배열에 있으며, 이는 이 버전이 커밋되지 않은 트랜잭션에 의해 생성되었으며 보이지 않음을 증명합니다.
    • b) trx_id가 배열에 없음을 증명합니다. 이 버전은 제출된 거래에 의해 생성되었음을 증명합니다.
  • 튜토리얼을 볼 때 약간 혼란스러웠던 세 번째 점은 다행히 일부 열정적인 네티즌들이 다음과 같이 대답했습니다. 녹색 영역은 거래 ID가 저수위와 고수위 범위 내에 있음을 의미하며, 실제로 표시되는지 여부는 녹색 영역에 이 값이 있는지 여부에 따라 달라집니다. 녹색 영역에 이 거래 ID가 없으면 표시되고, 있으면 표시되지 않습니다. 이 범위에 있다고 해서 이 범위에 [1,2,3,5]와 같은 값이 있다는 의미는 아닙니다. 4는 이 배열의 1-5 범위에 있지만 이 배열에는 없습니다.

이것은 다소 이해하기 어려울 수 있습니다. 3개의 트랜잭션이 동일한 데이터를 쿼리하고 업데이트한다고 가정합니다. 이해하기 쉽도록 그림을 그렸습니다.

원본 데이터는 여전히 아래 그림과 같습니다. , ID = 2인 Zhang San 정보 업데이트: MySQL의 트랜잭션 및 MVCC 원리를 자세히 설명하는 기사

위 사진과 관련하여 질문을 드리고 싶습니다. MySQL의 트랜잭션 및 MVCC 원리를 자세히 설명하는 기사RC(Read Committed) 및 RR(Repeatable Read) 격리 수준에서 각각 T4 및 T5 시점의 쿼리 수명 값은 무엇입니까? T4의 업데이트된 가치는 무엇인가요? 잠시 생각해보세요. 모두가 자신만의 답을 가지고 있다고 믿습니다. 답변은 기사 마지막 부분에 있습니다. 자신만의 질문을 가지고 계속해서 읽어보시기 바랍니다.

2.3.2 RR(반복 읽기)

RR 수준의 결과, 쿼리는 트랜잭션이 시작되기 전에 제출된 데이터만 인식하고, 트랜잭션이 시작되면 뷰가 빌드됩니다. 따라서 일관된 스냅샷 명령으로 트랜잭션 시작을 사용하면 뷰가 즉시 생성됩니다.

现在假设:

  • 事务 A 开始前,只有一个活跃的事务,ID = 2,
  • 已提交的事务也就是插入数据的事务 ID = 1
  • 事务 A、B、C 的事务 ID 分别是 3、4、5

在这种隔离级别下,他们创建视图的时刻如下:

MySQL의 트랜잭션 및 MVCC 원리를 자세히 설명하는 기사

根据上图得,事务 A 的视图数组是[2,3];事务 B 的视图数组是 [2,3,4];事务 C 的视图数组是[2,3,4,5]。分析一波:

  • T4 时刻,B 读数据都是从当前版本读起,过程是这样的:

    • 读到当前版本的 trx_id = 4,刚好是自己,可见
    • 所以 age = 24
  • T5 时刻,A 读数据都是从当前版本读起,过程是这样的:

    • 读到当前版本的 trx_id = 4,比自己视图数组的高水位大,不可见
    • 再往上读到 trx_id = 5,比自己视图数组高水位大,不可见
    • 再往上读到 trx_id = 1,比自己视图数组低水位小,可见
    • 所以 age = 22

这样执行下来,虽然期间这一行数据被修改过,但是事务 A 不论在什么时候查询,看到这行数据的结果都是一致的,所以我们称之为一致性读

其实视图是否可见主要看创建视图和提交的时机,总结下规律:

  • 版本未提交,不可见
  • 版本已提交,但在视图创建后提交,不可见
  • 版本已提交,但在视图创建前提交,可见

2.3.2.1 快照读和当前读

事务 B 的 update 语句,如果按照上图的一致性读,好像结果不大对?

如下图周明,B 的视图数组是先生成的,之后事务 C 才提交。那就应该看不见 C 修改的 age = 23 呀?最后 B 怎么得出 24 了?

MySQL의 트랜잭션 및 MVCC 원리를 자세히 설명하는 기사

没错,如果 B 在更新之前执行查询语句,那返回的结果肯定是 age = 22。问题是更新就不能在历史版本更新了呀,否则 C 的更新不就丢失了?

所以,更新有个规则:更新数据都是先读后写(读是更新语句执行,不是我们手动执行),读的就是当前版本的值,叫当前读;而我们普通的查询语句就叫快照读

因此,在更新时,当前读读到的是 age = 23,更新之后就成 24 啦。

2.3.2.2 select 当前读

除了更新语句,查询语句如果加锁也是当前读。如果把事务 A 的查询语句 select age from t where id = 2 改一下,加上锁(lock in mode 或者 for update),也都可以得到当前版本 4 返回的 age = 24

下面就是加了锁的 select 语句:

select age from t where id = 2 lock in mode;
 select age from t where id = 2 for update;
로그인 후 복사

2.3.2.3 事务 C 不马上提交

假设事务 C 不马上提交,但是 age = 23 版本已生成。事务 B 的更新将会怎么走呢?

事务 C 不马上提交

事务 C 还没提交,写锁还没释放,但是事务 B 的更新必须要当前读且必须加锁。所以事务 B 就阻塞了,必须等到事务 C 提交,释放锁才能继续当前的读。

被事务 C 锁住

2.3.3 RC(读提交)下的结果

在读提交隔离级别下,查询只承认在语句启动前就已经提交完成的数据;每一个语句执行之前都会重新算出一个新的视图

注意:在上图的表格中用于启动事务的是 start transaction with consistent snapshot 命令,它会创建一个持续整个事务的视图。所以,在  RC 级别下,这命令其实不起作用。等效于普通的 start transaction(在执行 sql 语句之前才算是启动了事务)。所以,事务 B 的更新其实是在事务 C 之后的,它还没真正启动事务,而 C 已提交

现在假设:

  • 트랜잭션 A가 시작되기 전에 활성화된 트랜잭션은 단 하나, ID = 2,
  • 커밋된 트랜잭션은 삽입된 데이터의 트랜잭션 ID = 1입니다.
  • 트랜잭션 A, B, C의 트랜잭션 ID는 3, 4,

이 격리 수준에서 뷰를 생성하는 순간은 다음과 같습니다.

MySQL의 트랜잭션 및 MVCC 원리를 자세히 설명하는 기사

위 그림에 따르면 트랜잭션 A의 뷰 배열은 [2,3,4]입니다. 그러나 상위 워터마크는 6 이상입니다(생성된 트랜잭션 ID + 1). 트랜잭션 B의 뷰 배열은 [2,4]입니다. 분석의 물결:

  • T4 시간에 B는 현재 버전의 데이터를 읽습니다. 프로세스는 다음과 같습니다.

    • 현재 버전의 trx_id = 4를 읽는 것을 볼 수 있습니다. 즉
    • so age = 24
  • T5 시점에 A는 현재 버전에서 데이터를 읽습니다. 프로세스는 다음과 같습니다.

    • 현재 버전의 trx_id = 4를 읽습니다. 이는 해당 범위 내에 있습니다. 자체 일관성 보기가 있지만 보이지 않는 4개를 포함합니다
    • 자신의 일관성 보기 범위 내에 있지만 5를 포함하지 않는 trx_id = 5까지 자세히 읽어보세요.
    • so age = 23
  • 을 볼 수 있습니다.

03 거인의 어깨

  • cnblogs.com/wyaokai/p /10921323.html
  • time.geekbang.org/column/article/70562
  • zhuanlan.zhihu.com/p/117476959
  • cn블로그 .com/xd502djj/p/6668632.html
  • blog.csdn.net/article /details/109044141
  • blog.csdn.net/u014078930/article/details/99659272

04 요약

이 기사에서는 네 가지 주요 기능, 격리 수준, 동시성 문제 해결, 설정 방법, 격리 수준 확인, 트랜잭션 시작 방법 등과 같은 트랜잭션의 모든 측면을 자세히 설명합니다. 또한 두 가지 격리 수준인 RR과 RC가 어떻게 달성되는지에 대한 심층적인 이해도 얻었습니다. MVCC, 실행 취소 로그 및 읽기 보기가 함께 작동하여 MVCC를 구현하는 방법에 대한 자세한 설명을 포함합니다. 마지막으로 스냅샷 읽기, 현재 읽기 등에 대해 이야기했습니다. 업무에 관련된 모든 지식 포인트가 여기에 있다고 할 수 있습니다. 이 글을 읽어도 여전히 이해가 안 되신다면, 와서 저를 때려주세요!

【관련 추천: mysql 비디오 튜토리얼

위 내용은 MySQL의 트랜잭션 및 MVCC 원리를 자세히 설명하는 기사의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:segmentfault.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿