0

0

MySQL安装如何设置事务隔离级别?并发控制详解

看不見的法師

看不見的法師

发布时间:2025-09-06 14:38:01

|

470人浏览过

|

来源于php中文网

原创

MySQL提供四种事务隔离级别:READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ和SERIALIZABLE,级别依次升高,分别控制脏读、不可重复读和幻读问题。REPEATABLE READ为InnoDB默认级别,通过MVCC和间隙锁在保证一致性的同时提升并发性能;READ COMMITTED避免脏读但允许不可重复读,适用于高并发场景;SERIALIZABLE通过串行化执行杜绝所有读异常,但性能开销大;READ UNCOMMITTED允许脏读,极少使用。隔离级别越高,数据一致性越强,并发性能越低,需根据业务权衡选择。

mysql安装如何设置事务隔离级别?并发控制详解

MySQL中设置事务隔离级别,通常在会话级别或全局级别进行。最直接的方式是使用

SET TRANSACTION ISOLATION LEVEL
命令,它决定了事务在并发操作中如何看到数据,以及如何避免各种并发问题。并发控制的本质,就是确保多个事务同时运行时,数据的完整性和一致性不受破坏,这背后涉及锁、MVCC等一系列复杂机制。

解决方案

在MySQL中,事务隔离级别的设置可以通过两种主要方式实现:全局设置和会话设置。

全局设置(对所有新会话生效):

SET GLOBAL TRANSACTION ISOLATION LEVEL [READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE];

例如,如果你希望所有新连接都默认使用

READ COMMITTED
,可以执行:

SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;

需要注意的是,这个设置只对新建立的会话生效,当前已经存在的会话不会受到影响。

会话设置(仅对当前会话生效):

SET SESSION TRANSACTION ISOLATION LEVEL [READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE];

或者,在事务开始前设置:

SET TRANSACTION ISOLATION LEVEL [READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE];
START TRANSACTION;
-- 你的SQL操作
COMMIT;

这种方式是针对当前会话的,其设置优先级高于全局设置。这意味着你可以在一个高并发系统中,全局默认一个性能较好的隔离级别(如

READ COMMITTED
),而对于某些对数据一致性要求极高的特定业务操作,可以在其事务开始前临时提升隔离级别(如
SERIALIZABLE
)。

要查看当前会话或全局的隔离级别,可以使用:

SELECT @@transaction_isolation; -- 或者 @@tx_isolation (旧版本)
SELECT @@global.transaction_isolation;

选择哪种隔离级别,是性能与数据一致性之间权衡的结果,没有银弹,需要根据具体的业务场景和对数据完整性的要求来决定。

MySQL的事务隔离级别有哪些,它们如何影响数据一致性?

MySQL,特别是InnoDB存储引擎,提供了四种标准的事务隔离级别,每种级别都在数据一致性和并发性能之间做出了不同的权衡。理解这些级别,实际上就是理解它们如何处理并发操作中可能出现的“读异常”:脏读(Dirty Read)、不可重复读(Non-Repeatable Read)和幻读(Phantom Read)。

Shakespeare
Shakespeare

一款人工智能文案软件,能够创建几乎任何类型的文案。

下载
  1. READ UNCOMMITTED (读未提交) 这是最低的隔离级别。一个事务可以读取到另一个未提交事务修改过的数据。

    • 影响: 允许“脏读”。这意味着你可能会读到一个最终被回滚的数据,导致你的业务逻辑基于错误的信息做出决策。这在实际应用中非常危险,极少使用。想象一下,一个转账事务还没完成,另一个查询已经看到了被扣款但未入账的状态,如果转账失败回滚,那之前看到的数据就成了“幻象”。
  2. READ COMMITTED (读已提交) 这是许多数据库(如PostgreSQL、Oracle)的默认隔离级别。一个事务只能读取到已经提交的事务修改过的数据。

    • 影响: 避免了“脏读”。但它仍然允许“不可重复读”。这意味着在同一个事务中,如果你两次读取同一行数据,第二次读取时可能会发现数据已经被另一个已提交的事务修改了,导致两次读取结果不一致。例如,你在一个事务里查询了用户A的余额是100,然后另一个事务给用户A转账并提交了,你再次查询用户A的余额,发现变成了200。
  3. REPEATABLE READ (可重复读) 这是MySQL InnoDB存储引擎的默认隔离级别。它确保在同一个事务中,多次读取同一行数据时,其结果始终一致。

    • 影响: 避免了“脏读”和“不可重复读”。但它仍然可能出现“幻读”。“幻读”指的是在一个事务中,你根据某个条件范围查询数据,然后另一个事务插入或删除了符合该条件的数据并提交,当你再次按相同条件查询时,会发现查询结果集的行数发生了变化。例如,你在一个事务中查询了所有年龄大于30的用户,然后另一个事务插入了一个新用户,年龄也大于30,你再次查询时,会发现多了一个用户。MySQL InnoDB通过MVCC和间隙锁(Gap Lock)的组合,在很大程度上解决了幻读问题,使得在
      REPEATABLE READ
      级别下,大部分情况下不会发生幻读。
  4. SERIALIZABLE (串行化) 这是最高的隔离级别。它强制事务串行执行,完全避免了“脏读”、“不可重复读”和“幻读”这三种读异常。

    • 影响: 提供了最严格的数据一致性,但以牺牲并发性能为代价。事务之间会进行严格的锁定,当一个事务在读数据时,其他事务不能修改;当一个事务在修改数据时,其他事务不能读写。这在并发量大的系统中通常是不可接受的,因为它会导致大量的超时和锁等待。

选择合适的隔离级别,是平衡数据完整性与系统吞吐量的关键。通常,

READ COMMITTED
REPEATABLE READ
是主流选择,具体取决于业务对数据一致性的要求和对性能的敏感度。

MySQL如何实现并发控制,除了隔离级别还有哪些核心机制?

事务隔离级别只是并发控制的一个高层抽象,MySQL在底层通过一系列精妙的机制来实现这些隔离保证。其中,InnoDB存储引擎是MySQL并发控制的核心,它主要依赖于以下几个关键技术:

  1. 多版本并发控制(Multi-Version Concurrency Control, MVCC) MVCC是InnoDB实现

    READ COMMITTED
    REPEATABLE READ
    隔离级别的基石。它的核心思想是:读操作不加锁,写操作(更新、删除)也不阻塞读操作,从而提高了数据库的并发性能。

    • 工作原理: 当数据被修改时,InnoDB并不会直接覆盖旧数据,而是为旧数据创建一个版本,并用一个回滚指针指向它。每个事务在启动时,都会获得一个唯一的事务ID(
      transaction_id
      )。当事务读取数据时,它会根据其自身的
      transaction_id
      和数据的版本信息(
      DB_TRX_ID
      DB_ROLL_PTR
      )来判断应该读取哪个版本的数据。
      • 对于
        READ COMMITTED
        ,事务每次读取都会看到最新的已提交版本。
      • 对于
        REPEATABLE READ
        ,事务在第一次读取时会创建一个快照(Read View),之后的所有读取都基于这个快照,无论其他事务提交了什么修改,当前事务看到的都是快照创建时的那个版本。这就是它如何避免不可重复读的。
    • MVCC极大地减少了读写冲突,使得高并发系统能够保持良好的响应速度。
  2. 锁机制(Locking) 尽管MVCC处理了大部分读写冲突,但写写冲突(两个事务同时修改同一行)以及在

    SERIALIZABLE
    隔离级别下,仍然需要通过锁来保证数据的一致性。

    • 共享锁(Shared Lock, S Lock): 允许事务读取一行数据。多个事务可以同时持有同一行数据的S锁。
    • 排他锁(Exclusive Lock, X Lock): 允许事务修改或删除一行数据。当一个事务持有X锁时,其他事务不能再对该行加任何锁。
    • 意向锁(Intention Lock, IS/IX Lock): 这是表级锁,用于指示事务将要在表中的某些行上设置S锁或X锁。它的作用是快速判断表是否存在行级锁,避免扫描整个表来检查。
    • 记录锁(Record Lock): 锁定索引中的一条记录。
    • 间隙锁(Gap Lock): 锁定索引记录之间的间隙,防止其他事务在这个间隙中插入新的记录。这是InnoDB在
      REPEATABLE READ
      级别下解决“幻读”的关键。
    • Next-Key Lock: 记录锁和间隙锁的组合,锁定一条记录及其之前的间隙。
    • 死锁(Deadlock): 当两个或多个事务互相等待对方释放锁时,就会发生死锁。InnoDB有一个死锁检测机制,它会选择一个事务作为“牺牲品”并回滚它,从而解除死锁。
  3. Undo Log(回滚日志) Undo Log是实现MVCC和事务回滚的关键。它记录了事务对数据进行的修改操作的逆操作。

    • MVCC: 当事务需要读取旧版本数据时,会通过Undo Log找到并重建出相应的数据版本。
    • 事务回滚: 如果事务失败或被显式回滚,InnoDB会利用Undo Log来撤销所有已做的修改,将数据恢复到事务开始前的状态。
  4. Redo Log(重做日志) Redo Log用于保证事务的持久性(Durability)。它记录了事务对数据页所做的物理修改。

    • 崩溃恢复: 即使数据库在事务提交后、数据写入磁盘前发生崩溃,MySQL也能通过Redo Log在重启时重新执行这些操作,确保已提交的数据不会丢失。

这些机制协同工作,共同构成了MySQL InnoDB强大而复杂的并发控制体系,使得数据库能够在高并发环境下,既保证数据一致性,又提供良好的性能。

何时应该调整MySQL的默认事务隔离级别,以及这样做会带来哪些性能影响?

调整MySQL的默认事务隔离级别是一个需要深思熟虑的决定,因为它直接关系到数据一致性、并发性能和开发复杂度。默认的

REPEATABLE READ
在大多数情况下表现良好,但在某些特定场景下,你可能需要进行调整。

  1. 何时考虑提升隔离级别(如到

    SERIALIZABLE
    )?

    • 极端数据一致性要求: 如果你的业务对数据一致性的要求达到了最高级别,即使是微小的“幻读”都无法容忍,例如涉及金融结算、库存核算等核心业务逻辑,且这些操作的并发量相对较低,那么
      SERIALIZABLE
      可能是唯一选择。
    • 性能影响: 提升到
      SERIALIZABLE
      会显著降低系统的并发能力,因为所有事务几乎都是串行执行的。这会导致大量的锁等待和事务超时,严重影响吞吐量。在OLTP(在线事务处理)系统中,这种级别通常是不可接受的。因此,除非有极其严格的业务需求,否则应尽量避免。
  2. 何时考虑降低隔离级别(如到

    READ COMMITTED
    )?

    • 高并发OLTP系统: 在高并发的在线事务处理系统中,
      REPEATABLE READ
      的间隙锁可能会导致不必要的锁竞争和死锁,从而降低性能。
      READ COMMITTED
      只对记录加锁,不加间隙锁(除非是外键约束检查),这通常能提供更好的并发性。
    • 减少锁等待和死锁:
      READ COMMITTED
      由于不使用间隙锁,可以有效减少锁的范围,降低死锁的发生概率。
    • 数据一致性权衡: 降低到
      READ COMMITTED
      意味着你接受了“不可重复读”的可能性。这意味着在一个事务中,你可能会看到同一行数据在两次查询之间发生变化。如果你的业务逻辑能够容忍这种不一致(例如,很多报表系统或者对实时性要求不那么高的分析查询),或者你的应用层可以处理这种不一致(例如,通过在应用层加锁或重试),那么
      READ COMMITTED
      是一个很好的选择。
    • 性能影响: 切换到
      READ COMMITTED
      通常能提高系统的并发吞吐量,因为它减少了锁的持有时间,也降低了锁的粒度。这对于读写混合且并发量大的应用来说,是一个常见的优化手段。
  3. 何时考虑使用

    READ UNCOMMITTED

    • 极少使用: 除非你有一个纯粹的、对数据一致性完全不敏感的查询场景(例如,一些日志分析,即使数据有微小偏差也无所谓),否则几乎不应使用
      READ UNCOMMITTED
      。它带来的“脏读”风险太高,可能导致严重的业务逻辑错误。
    • 性能影响: 理论上,
      READ UNCOMMITTED
      提供了最高的并发性,因为它几乎不对读操作加锁。但这种性能提升是以牺牲数据正确性为代价的,风险远大于收益。

总结性能影响:

  • 隔离级别越高,数据一致性越好,但并发性能越差。
  • 隔离级别越低,并发性能越好,但数据一致性风险越高。

在实际项目中,我们常常会发现,为了提高并发,许多高流量的应用会选择将全局隔离级别设置为

READ COMMITTED
。但即便如此,对于某些关键业务逻辑,依然可能在事务开始前通过
SET TRANSACTION ISOLATION LEVEL
命令临时提升隔离级别,以确保核心数据操作的绝对一致性。这是一个典型的在性能和数据完整性之间进行动态权衡的实践。在做任何调整前,务必在测试环境中进行充分的压力测试和场景验证,确保新的隔离级别不会引入新的问题。

相关专题

更多
mysql修改数据表名
mysql修改数据表名

MySQL修改数据表:1、首先查看数据库中所有的表,代码为:‘SHOW TABLES;’;2、修改表名,代码为:‘ALTER TABLE 旧表名 RENAME [TO] 新表名;’。php中文网还提供MySQL的相关下载、相关课程等内容,供大家免费下载使用。

664

2023.06.20

MySQL创建存储过程
MySQL创建存储过程

存储程序可以分为存储过程和函数,MySQL中创建存储过程和函数使用的语句分别为CREATE PROCEDURE和CREATE FUNCTION。使用CALL语句调用存储过程智能用输出变量返回值。函数可以从语句外调用(通过引用函数名),也能返回标量值。存储过程也可以调用其他存储过程。php中文网还提供MySQL创建存储过程的相关下载、相关课程等内容,供大家免费下载使用。

246

2023.06.21

mongodb和mysql的区别
mongodb和mysql的区别

mongodb和mysql的区别:1、数据模型;2、查询语言;3、扩展性和性能;4、可靠性。本专题为大家提供mongodb和mysql的区别的相关的文章、下载、课程内容,供大家免费下载体验。

281

2023.07.18

mysql密码忘了怎么查看
mysql密码忘了怎么查看

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql密码忘了怎么办呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

514

2023.07.19

mysql创建数据库
mysql创建数据库

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql怎么创建数据库呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

255

2023.07.25

mysql默认事务隔离级别
mysql默认事务隔离级别

MySQL是一种广泛使用的关系型数据库管理系统,它支持事务处理。事务是一组数据库操作,它们作为一个逻辑单元被一起执行。为了保证事务的一致性和隔离性,MySQL提供了不同的事务隔离级别。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

386

2023.08.08

sqlserver和mysql区别
sqlserver和mysql区别

SQL Server和MySQL是两种广泛使用的关系型数据库管理系统。它们具有相似的功能和用途,但在某些方面存在一些显著的区别。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

530

2023.08.11

mysql忘记密码
mysql忘记密码

MySQL是一种关系型数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。那么忘记mysql密码我们该怎么解决呢?php中文网给大家带来了相关的教程以及其他关于mysql的文章,欢迎大家前来学习阅读。

599

2023.08.14

Java JVM 原理与性能调优实战
Java JVM 原理与性能调优实战

本专题系统讲解 Java 虚拟机(JVM)的核心工作原理与性能调优方法,包括 JVM 内存结构、对象创建与回收流程、垃圾回收器(Serial、CMS、G1、ZGC)对比分析、常见内存泄漏与性能瓶颈排查,以及 JVM 参数调优与监控工具(jstat、jmap、jvisualvm)的实战使用。通过真实案例,帮助学习者掌握 Java 应用在生产环境中的性能分析与优化能力。

19

2026.01.20

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
【web前端】Node.js快速入门
【web前端】Node.js快速入门

共16课时 | 2万人学习

MySQL 初学入门(mosh老师)
MySQL 初学入门(mosh老师)

共3课时 | 0.3万人学习

简单聊聊mysql8与网络通信
简单聊聊mysql8与网络通信

共1课时 | 804人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号