首页 > 数据库 >如何理解mysql 的事务隔离级别 repeatable read

如何理解mysql 的事务隔离级别 repeatable read

时间:2024-07-04 22:30:58浏览次数:9  
标签:事务 隔离 read READ REPEATABLE repeatable mysql 级别 读取

在MySQL中,事务隔离级别定义了事务之间如何相互隔离,以及数据的一致性和并发性如何平衡。REPEATABLE READ(可重复读)是MySQL中四种事务隔离级别之一,它在保证数据一致性的同时,允许较高的并发性。

MySQL的四种事务隔离级别

  1. READ UNCOMMITTED(未提交读)
  2. READ COMMITTED(提交读)
  3. REPEATABLE READ(可重复读)
  4. SERIALIZABLE(可串行化)

这四种隔离级别从低到高分别提供了不同程度的数据一致性和并发控制。

REPEATABLE READ 的特性

REPEATABLE READ 隔离级别下,事务在执行 SELECT 语句时,会看到在该事务开始时存在的数据状态。这意味着在同一个事务中多次读取同一行数据,结果是相同的,即使其他事务已经对数据进行了修改并提交。这种行为防止了不可重复读(non-repeatable read),即在同一事务中多次读取同一行数据得到不同结果的问题。

为了更好地理解 REPEATABLE READ,需要理解以下几个关键概念:

1. 多版本并发控制(MVCC)

MySQL的InnoDB存储引擎通过使用MVCC实现 REPEATABLE READ。MVCC允许事务在读取数据时,不需要加锁,从而提高并发性能。每行数据有多个版本,事务读取的数据版本是在事务开始时的数据快照(snapshot)。这种机制使得读取操作不会阻塞写入操作,反之亦然。

2. 快照读(Snapshot Read)

REPEATABLE READ 隔离级别下,普通的 SELECT 语句是快照读。快照读从事务开始时的快照读取数据,不会受到其他事务修改数据的影响。

3. 当前读(Current Read)

SELECT ... FOR UPDATESELECT ... LOCK IN SHARE MODE 语句是当前读。当前读读取的是最新的数据,并且会锁定读取的数据行以防止其他事务修改。这种读方式用于需要对数据进行后续修改的场景。

4. 幻读(Phantom Read)

REPEATABLE READ 隔离级别还解决了幻读问题。幻读是指在同一事务中两次执行相同的查询,但结果集不一致的问题。例如,在第一次查询时没有新插入的行,但在第二次查询时有其他事务插入了新行。InnoDB通过间隙锁(Gap Lock)和Next-Key锁机制解决了幻读问题。

示例

假设有一个表 employees,结构如下:

CREATE TABLE employees (
    id INT PRIMARY KEY,
    name VARCHAR(100),
    salary DECIMAL(10, 2)
);

事务A:

START TRANSACTION;
SELECT * FROM employees WHERE id = 1;
-- 返回结果:{ id: 1, name: 'John', salary: 5000.00 }

事务B:

START TRANSACTION;
UPDATE employees SET salary = 6000.00 WHERE id = 1;
COMMIT;

事务A:

SELECT * FROM employees WHERE id = 1;
-- 仍然返回结果:{ id: 1, name: 'John', salary: 5000.00 }
COMMIT;

在事务A中,即使事务B已经提交了更新,事务A在第二次读取时依然看到的是事务开始时的数据快照。

也就是说REPEATABLE READ 隔离级别通过MVCC机制,确保在一个事务中多次读取相同数据时结果一致,防止了不可重复读和幻读问题,同时在不锁定数据的情况下允许较高的并发性。这种隔离级别是MySQL InnoDB存储引擎的默认隔离级别,适用于大多数应用场景,在提供数据一致性的同时,具有较好的并发性能。

标签:事务,隔离,read,READ,REPEATABLE,repeatable,mysql,级别,读取
From: https://www.cnblogs.com/gongchengship/p/18284813

相关文章

  • 安装MySQL
    win1.下载安装包地址:https://dev.mysql.com/downloads/mysql/下载完成,解压2.配置系统变量变量名:MYSQL_HOME变量值:D:\app\mysql-8.4.1-winx643.安装MySQLD:\app\mysql-8.4.1-winx64\bin>mysqld--initialize-insecure--user=mysqlD:\app\mysql-8.4.1-winx64\bin>mysql......
  • mysql 8详细安装过程(windows 11)
        本次在windows11中安装mysql-8.4.1的压缩版。需要注意的是,其中涉及的安装配置比较多,以及需要执行的命令较多,建议大家收藏保存。一、安装环境二、下载mysql    下载地址:MySQL::DownloadMySQLCommunityServer如果没有oracle账号,点击上面下......
  • 查看 mysql 版本号
    mysql--versionmysqlVer8.3.0formacos14.2onarm64(Homebrew)mysql--helpmysqlVer8.3.0formacos14.2onarm64(Homebrew)Copyright(c)2000,2024,Oracleand/oritsaffiliates.OracleisaregisteredtrademarkofOracleCorporationand/or......
  • Mysql安装步骤(centos7)
    MySQL安装步骤(CentOS-7)1、更新yum源rpm-Uvhhttp://dev.mysql.com/get/mysql57-community-release-el7-9.noarch.rpm2、安装MySQLyum-yinstallmysql-community-server--nogpgcheck3、查看MySQL版本号mysql-V4、启动MySQL服务systemctlstartmysqld5、设置开......
  • ElasticSearch 如何增加相当于MySql 中的一列字段
    在Elasticsearch中,增加相当于MySQL中的一列字段的操作被称为“添加字段到索引映射”。与MySQL不同,Elasticsearch是一个文档存储引擎,使用索引和类型来组织数据。每个文档都有其特定的映射(mapping),定义了字段及其数据类型。增加字段到Elasticsearch映射的步骤查看当前映射:首先,查......
  • MySQL的事务默认隔离级别是什么
    MySQL的默认隔离级别是REPEATABLEREAD。隔离级别概述数据库的隔离级别决定了事务相互隔离的程度,从而影响到并发事务的行为。SQL标准定义了四种隔离级别:READUNCOMMITTED(未提交读)READCOMMITTED(提交读)REPEATABLEREAD(可重复读)SERIALIZABLE(可串行化)每种隔离级别解决不......
  • mysql主从复制
    一、主从复制通过主从复制,可以实现读写分离。1.什么是主从复制MySQL主从复制是一种数据库复制技术,用于将一个MySQL数据库服务器的更改同步到其他MySQL数据库服务器。在主从复制中,有一个主数据库(Master)和一个或多个从数据库(Slave)。主数据库负责接收和处理所有的写操作,而从数据......
  • “Java多线程编程:从Thread到Runnable再到Callable的深入探索“
    1什么是进程?通俗地解释为:计算机中正在执行的一个程序实例。进程它是系统分配资源的基本单位。想象一下,你的电脑就像是一个大工厂,而每一个进程就像是这个工厂里的一条生产线或者一个工作小组,它们各自独立地运行着不同的任务,但同时又受到整个工厂(即操作系统)的管理和调度。......
  • SAAS下一个mysql实例多个租户的库
    在多租户环境中,根据tenantCode字段动态切换数据库是常见的需求。这里将展示如何在SpringBoot和MyBatis项目中实现这一功能,具体步骤包括配置数据源、定义数据源路由逻辑以及在业务代码中使用。1.配置数据源首先,你需要为你的应用配置一个主数据源,这个数据源将被用于连接到包含所......
  • QThread::run函数的使用(涉及到QThread::run, Qthread::start,protected,virtual虚函数,o
    RobotCommuServer.h#ifndefROBOTCOMMUSERVER_H#defineROBOTCOMMUSERVER_H#include<QThread>classRobotCommuServer:publicQThread{Q_OBJECTpublic:explicitRobotCommuServer(QObject*parent=nullptr);~RobotCommuServer();void......