MySQL中的事务隔离级别有哪些

MySQL中的事务隔离级别

  • 一、事务并发问题
  • [二、MySQL 事务隔离级别](#二、MySQL 事务隔离级别)
    • [1. READ UNCOMMITTED(读未提交)](#1. READ UNCOMMITTED(读未提交))
    • [2. READ COMMITTED(读已提交)](#2. READ COMMITTED(读已提交))
    • [3. REPEATABLE READ(可重复读)(MySQL 默认级别)](#3. REPEATABLE READ(可重复读)(MySQL 默认级别))
    • [4. SERIALIZABLE(可串行化)](#4. SERIALIZABLE(可串行化))
  • [三、MySQL 默认事务隔离级别](#三、MySQL 默认事务隔离级别)
  • 四、不同隔离级别对并发问题的影响
  • 五、如何选择合适的隔离级别?
  • 总结

在MySQL中,事务(Transaction)是一个执行单元,它要么完全执行,要么完全回滚,以保证数据的完整性和一致性。事务的隔离性(Isolation)是ACID特性之一,它控制了多个事务同时执行时,数据的可见性。MySQL 提供了四种事务隔离级别,每种级别都会影响事务之间的相互影响程度。

一、事务并发问题

在多个事务同时操作同一份数据时,可能会出现以下几种并发问题:

  1. 脏读(Dirty Read):一个事务读取了另一个未提交事务修改的数据,如果后者回滚,则前者读取到的数据是无效的。
  2. 不可重复读(Non-repeatable Read):同一个事务中,执行两次相同的查询,由于另一个事务的提交,查询结果不同。
  3. 幻读(Phantom Read):一个事务在两次查询之间,另一事务插入或删除了数据,导致前后查询的记录数不一致。

为了避免这些问题,SQL 标准定义了四种事务隔离级别,MySQL 也支持这四种级别。

二、MySQL 事务隔离级别

MySQL 通过 SET TRANSACTION ISOLATION LEVEL 语句来设置事务隔离级别:

sql 复制代码
SET SESSION TRANSACTION ISOLATION LEVEL <级别>;
SET GLOBAL TRANSACTION ISOLATION LEVEL <级别>;

其中 <级别> 可以是 READ UNCOMMITTEDREAD COMMITTEDREPEATABLE READSERIALIZABLE

1. READ UNCOMMITTED(读未提交)

  • 特点

    • 事务可以读取其他未提交事务的数据。
    • 可能发生"脏读"问题。
    • 性能较好,因为不会使用锁限制读取。
  • 示例

    • 事务A修改了一条记录但尚未提交。
    • 事务B在事务A提交之前读取了修改后的数据。
    • 如果事务A回滚,那么事务B读取到的数据就是"脏数据"。
  • 适用场景

    • 允许读取未提交的数据,适用于不太关心数据一致性的应用,如日志记录、监控数据等。

2. READ COMMITTED(读已提交)

  • 特点

    • 只能读取已经提交的数据,避免了"脏读"。
    • 可能发生"不可重复读"问题。
    • MySQL InnoDB 通过 MVCC(多版本并发控制)来实现此隔离级别。
  • 示例

    • 事务A读取一条记录。
    • 事务B修改该记录并提交。
    • 事务A再次读取该记录,发现数据发生了变化(不可重复读)。
  • 适用场景

    • 适用于大多数 OLTP(在线事务处理)系统,如银行转账、订单管理系统,保证读取的数据是已提交的但允许数据更新。

3. REPEATABLE READ(可重复读)(MySQL 默认级别)

  • 特点

    • 事务内多次读取同一条数据时,数据保持一致(即使其他事务修改并提交了数据)。
    • 通过 MVCC 实现可重复读。
    • 避免了"脏读"和"不可重复读"。
    • 但仍然可能发生"幻读"问题。
  • 示例

    • 事务A第一次读取某条数据。
    • 事务B修改该数据并提交。
    • 事务A再次读取该数据,发现数据未改变(因为事务A读取的是事务开始时的快照)。
  • 如何解决幻读?

    • MySQL InnoDB 通过 间隙锁(Next-Key Locking) 机制来解决幻读问题,即锁住范围,使得其他事务无法插入新的数据,从而防止幻读。
  • 适用场景

    • 适用于高并发场景,尤其是金融行业,如银行账户查询和订单管理系统。

4. SERIALIZABLE(可串行化)

  • 特点

    • 最高级别的隔离,完全避免脏读、不可重复读和幻读。
    • 事务必须依次执行,不能并行,通常会使用 表锁行锁
    • 并发性能极差,适用于对数据一致性要求极高的场景。
  • 示例

    • 事务A读取某一条数据,同时事务B必须等事务A完成后才能读取或修改该数据。
  • 适用场景

    • 适用于需要严格数据一致性的场景,如财务结算、票务系统等。

三、MySQL 默认事务隔离级别

MySQL InnoDB 存储引擎的默认事务隔离级别是 REPEATABLE READ(可重复读) ,这与 SQL 标准的默认级别(READ COMMITTED)不同。MySQL 通过 MVCC (多版本并发控制)和 间隙锁 解决了幻读问题,因此 REPEATABLE READ 在 MySQL 中比 SQL 标准更强

如果想修改默认的事务隔离级别,可以在 my.cnf(MySQL 配置文件)中修改:

ini 复制代码
[mysqld]
transaction-isolation = REPEATABLE-READ

或在运行时更改:

sql 复制代码
SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;

四、不同隔离级别对并发问题的影响

隔离级别 脏读(Dirty Read) 不可重复读(Non-repeatable Read) 幻读(Phantom Read)
READ UNCOMMITTED 可能发生 ✅ 可能发生 ✅ 可能发生 ✅
READ COMMITTED 不会发生 ❌ 可能发生 ✅ 可能发生 ✅
REPEATABLE READ 不会发生 ❌ 不会发生 ❌ 可能发生 ✅(MySQL 中不会)
SERIALIZABLE 不会发生 ❌ 不会发生 ❌ 不会发生 ❌

五、如何选择合适的隔离级别?

  • READ UNCOMMITTED:适用于对数据一致性要求不高的场景,如日志分析、缓存数据等。
  • READ COMMITTED:适用于大多数业务场景,如电商系统、用户管理系统等,避免脏读,提高并发性能。
  • REPEATABLE READ(MySQL 默认):适用于金融系统、库存管理,保证事务内数据的一致性,防止不可重复读。
  • SERIALIZABLE:适用于对数据一致性要求极高的场景,如银行结算、核心财务系统,但性能损耗较大。

总结

  • READ UNCOMMITTED:可能发生脏读、不可重复读、幻读,性能最高但安全性最低。
  • READ COMMITTED:防止脏读,但可能发生不可重复读和幻读。
  • REPEATABLE READ(MySQL 默认):防止脏读和不可重复读,MySQL 还能避免幻读,适用于大多数高并发业务。
  • SERIALIZABLE:所有并发问题都能避免,但性能最差。

MySQL 默认采用 REPEATABLE READ ,主要是因为 MySQL 通过 MVCC 解决了大部分的并发问题,既能保持较高的事务隔离级别,又不会影响太多的性能。


MySQL中的事务隔离级别有四种,分别为:

  1. 读未提交(Read Uncommitted)

    • 该级别允许事务读取其他事务尚未提交的数据(脏读)。这意味着一个事务可以读取到另一个事务中间状态的数据,可能会导致数据不一致。
  2. 读已提交(Read Committed)

    • 该级别保证事务只能读取到已提交的数据,防止脏读。即使如此,仍然允许发生"不可重复读"(在同一事务中两次读取同一数据,值可能不同,因为另一个事务已经修改了数据并提交)。
  3. 可重复读(Repeatable Read)

    • 该级别保证在一个事务中多次读取同一数据时,结果始终一致,避免了"不可重复读"。但是,仍然可能会出现"幻读"(即事务读取的结果集发生了变化,因为另一个事务插入了新的记录)。
  4. 串行化(Serializable)

    • 这是最高的隔离级别,强制事务串行执行,即事务排队执行,一个事务在完成之前,其他事务无法访问相同的数据。这可以完全避免脏读、不可重复读和幻读,但性能会较低。
相关推荐
异世界贤狼转生码农1 小时前
MongoDB Windows 系统实战手册:从配置到数据处理入门
数据库·mongodb
QuZhengRong2 小时前
【数据库】Navicat 导入 Excel 数据乱码问题的解决方法
android·数据库·excel
码农阿豪2 小时前
Windows从零到一安装KingbaseES数据库及使用ksql工具连接全指南
数据库·windows
冷崖7 小时前
MySQL异步连接池的学习(五)
学习·mysql
时序数据说7 小时前
时序数据库市场前景分析
大数据·数据库·物联网·开源·时序数据库
听雪楼主.11 小时前
Oracle Undo Tablespace 使用率暴涨案例分析
数据库·oracle·架构
我科绝伦(Huanhuan Zhou)11 小时前
KINGBASE集群日常维护管理命令总结
数据库·database
妖灵翎幺11 小时前
Java应届生求职八股(2)---Mysql篇
数据库·mysql
HMBBLOVEPDX11 小时前
MySQL的事务日志:
数据库·mysql
weixin_4196583113 小时前
MySQL数据库备份与恢复
数据库·mysql