Mysql事务隔离级别是怎么实现的?
创始人
2024-03-21 15:00:35
0次

文章目录

    • 事务隔离级别
      • 解析
    • 常用命令
      • 查看事务隔离级别设置
      • 修改隔离级别
      • 隔离级别演示
      • Mysql事务操作
    • MVCC实现原理
      • undo log版本链
      • ReadView
    • 练习一下
      • 案例1
      • 案例2
    • 问答环节
      • 1、Mysql 可重复读到底有没有解决幻读?

事务隔离级别

Mysql的事务隔离级别是由Mysql的各种锁以及MVCC机制来实现的。
不同隔离级别存在的问题:
在这里插入图片描述

在Mysql Innodb存储引擎下,RC、RR是基于MVCC(多版本并发控制)进行并发事务控制的。
先来看一个问题,先想一下在不同隔离级别下,事务D读取到的内容是什么?

解析

Undo Log版本链
在这里插入图片描述

RC隔离级别时的ReadView:
在这里插入图片描述

常用命令

查看事务隔离级别设置

# 查看事务隔离级别 5.7.20 之后
show variables like 'transaction_isolation';
SELECT @@transaction_isolation# 5.7.20 之后
SELECT @@tx_isolation
show variables like 'tx_isolation'+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| tx_isolation  | REPEATABLE-READ |
+---------------+-----------------+

修改隔离级别

完整设置语句

SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}

案例:设置全局隔离级别为读提交级别。

mysql> set global transaction isolation level read committed;

隔离级别演示

set tx_isolation='read-committed';
BEGAIN;
UPDATE t_user set name = '子涵先生';​
COMMIT;

Mysql事务操作

Mysql事务开启有两种方式:

  • begin/start transaction:begin/start transaction 命令并不是一个事务的起点,在执行到它们之后的第一个操作InnoDB表的语句,事务才真正启动。
  • start transaction with consistent snapshot:这个命令可以立即启动一个事务。

InnoDB里面每个事务有一个唯一的事务ID,叫作transaction id。它是在事务开始的时候向InnoDB的事务系统申请的,是按申请顺序严格递增的。

MVCC实现原理

MVCC的实现原理是基于:undolog版本链+Readview。

undo log版本链

  • trx_id:事务版本号,自增;
  • DB_ROLL_PTR(回滚指针):指向上一个版本的数据。
    在这里插入图片描述

UBDO_LOG版本链不是立即删除的,Mysql在确保版本链数据不再被“引用”后才会进行删除。

ReadView

ReadView的作用:从版本链中读取数据,数据读取的时候为“快照读”。

补充一下:

  1. 快照读:普通的select查询语句;
  2. 当前读:Insert、Update、Delete、Select … for update、Select …lock in share mode。

ReadView的结构:

  • m_ids:表示在生成readview时,当前系统中活跃的读写事务id列表;
  • min_trx_id:表示在生成readview时,当前系统中活跃的读写事务中最小的事务id,也就是m_ids中最小的值;
  • max_trx_id:表示生成readview时,系统中应该分配给下一个事务的id值;
  • creator_trx_id:表示生成该readview的事务的事务id。

MVCC中的数据读取规则:

  1. 优先读取当前事务版本中的数据;
  2. 否则根据版本链找到非活跃事务中的数据。

READ COMMITTED和REPEATABLE READ均是基于MVCC实现的,其区别就在于ReadView中的的生成时机:

  • READ COMMITTED生成时机是在每次查询时;
  • REPEATABLE READ是在当前事务开启时创建的。

练习一下

案例1

事务A:

select * from user where user_name ='张三';  -- 张三user_age为50
-- 此时事务B执行一下
select * from user where user_name ='张三';  -- question1:在两种不同的事务隔离级别下,张三user_age为结果为多少?

事务B:

insert into user (user_name,user_age) values ('张三',25);

案例2

事务A:

select * from user where user_name ='张三';  -- 张三user_age为50
-- 此时事务B执行一下
select * from user where user_name ='张三';  -- question1:张三user_age为结果为多少?
update set user_age = 100 where user_name ='张三'; 
select * from user where user_name ='张三';  -- question2:张三user_age为结果为多少?

事务B:

insert into user (user_name,user_age) values ('张三',25);

问答环节

1、Mysql 可重复读到底有没有解决幻读?

幻读的官网解释:The so-calledphantomproblem occurs within a transaction when the same query produces different sets of rows at different times. For example, if aSELECTis executed twice, but returns a row the second time that was not returned the first time, the row is a“phantom”row.

能,但不完全能,遇到当前读的时候,ReadView会被重新创建,可以读取到其他事务提交后被新增的数据。

相关内容

热门资讯

前端-session、jwt 目录:   (1)session (2&#x...
linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
关于测试,我发现了哪些新大陆 关于测试 平常也只是听说过一些关于测试的术语,但并没有使用过测试工具。偶然看到编程老师...
前缀和与对数器与二分法 1. 前缀和 假设有一个数组,我们想大量频繁的去访问L到R这个区间的和,...
nodejs:本地安装nvm实... 一、背景-使用不同版本node的原因 vue3+ts、nuxt3版本,node...
JAVA集合知识整理 Java集合知识整理 HashMap相关 HashMap的底层数据结构:jdk1.8之...
无刷直流电机介绍及单片机控制实... 无刷直流电机介绍及单片机控制实例前言基本概念优势与劣势使用寿命基本结构使用单片机控制实例电子调速器&...
fwdiary(2) dp2 1.传纸条  AcWing 275. 传纸条 - AcWing 走两条路,走一条最大的...
常用的DOS命令 常用的DOS命令 DOS(Disk Operating System,磁...
<C++> 类和对象(下) 1.const成员函数将const修饰的“成员函数”称之为const成员函数,cons...