返回顶部
分享到

一文介绍mysql的事务、锁以及MVCC

Mysql 来源:互联网 作者:佚名 发布时间:2025-12-22 21:04:06 人浏览
摘要

四种隔离级别 一般默认是RR,即可重复读。如果是互联网公司,为了避免锁等待,一般是RC。 读未提交(Read Uncommitted) 会导致脏读。读到了其他事务还没提交的数 读已提交RC(Read Committed)

四种隔离级别

一般默认是RR,即可重复读。如果是互联网公司,为了避免锁等待,一般是RC。

  1. 读未提交(Read Uncommitted)
    会导致脏读。读到了其他事务还没提交的数

  2. 读已提交RC(Read Committed)
    一个事务只能读取到其他事务已经提交的更改。
    会导致不可重读:由于另一个事务提交的影响,导致两次读取的结果不一样。

  3. 可重复读RR(Repeatable Read)
    默认的隔离级别。在这个级别下,保证在同一个事务内,多次读取同一数据的结果是一致的。
    但是会有幻读问题,幻读是一种特殊的不可重复读。为啥说是特殊的不可重复读呢?因为幻读是范围性的不可重复读。事务A执行select …where前后,如果其他事务执行insert语句插入了满足where条件的记录,那么事务A的两次查询结果会不一样。
    需要注意的是,mysql添加了next-key临键锁(行锁+间隙锁)来解决了幻读。
    4.可序列化
    读加共享锁,写加排他锁,读写互斥。使用的悲观锁的理论,实现简单,数据更加安全,但是并发能力非常差。如果你的业务并发的特别少或者没有并发,同时又要求数据及时可靠的话,可以使用这种模式。

MVCC

明确一点,锁、MVCC这些东西都是为了保证ACID的。

锁机制是通过锁定资源(如表、行)来防止并发操作之间的冲突,确保数据一致性。

加锁完全可以解决上面提到的脏读、不可重复读、幻读的问题。就像“可序列化”隔离级别一样,如果什么都加锁,会导致读写时,必然有一方等待,降低了并发能力。所以为了提高性能,基于乐观锁思想,才采用了MVCC来解决问题。所以数据库是乐观锁+悲观锁一起来使用的。
MVCC(多版本并发控制)则是通过维护数据的多个版本,让读操作无需等待写操作完成,从而提高并发性能,同时保证事务隔离性。(会将每一次修改的数据用一个链表链接好,相当于历史记录)。mysql 数据库中,每一条数据都保存一个创建时的版本号和一个删除版本号,MVCC就是根据这两个来发挥作用的。

多版本并发控制的一个简单使用就是,查询时select version,xxx,xx where id = 1读出来,此时version=1。修改数据时版本号+1,update xx ... where id = 1 and version =2,如果返回1说明修改成功,如果返回0,可以提示用户有冲突等。

快照读/当前读

  • 快照读:读取的是历史数据,非最新的数据
  • 当前读 :读取最新数据
  • 快照读:就是select
    select * from table ….;
  • 当前读:特殊的读操作,插入/更新/删除操作,属于当前读,处理的都是当前的数据,需要加锁。
     

    1

    2

    3

    4

    5

    select * from table where ? lock in share mode;

    select * from table where ? for update;

    insert;

    update ;

    delete;

MVCC:解决了读操作时的不可重复读和幻读
临键锁:解决了写操作时的幻读(当前读、更新、删除)。
为啥这么说呢?
看下,在RR隔离级别下,如何解决不可重复读、幻读呢?可重复读其实读到的是历史数据,这叫快照读。只会读取历史数据,不用加锁。其他事务此时insert或update或delete的话,他们的创建版本号或者删除版本号会改变。此时insert的话,假如创建版本号是10。而另一个RR事务版本号是5。MVCC规定,事务版本号是5的话,select的时候,只能查到 创建版本号<=5的数据。所以不会查到创建版本号是10的数据。其实这也解决了幻读。从这里可以看出,MVCC只能解决快照读场景下面的幻读,不能解决当前读场景下的幻读。举个例子:
·SELECT … FOR UPDATE·,这是当前读,直接加锁需要读取最新的数据,那么MVCC就没啥用了。此时再插入一行新记录,那么select也会查出该条记录来。所以该场景下出现了临键锁。

注意临键锁是加在索引上面的,如果没有索引,可能会锁全表。

锁和MVCC对比


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 :
相关文章
  • 一文介绍mysql的事务、锁以及MVCC

    一文介绍mysql的事务、锁以及MVCC
    四种隔离级别 一般默认是RR,即可重复读。如果是互联网公司,为了避免锁等待,一般是RC。 读未提交(Read Uncommitted) 会导致脏读。读到了
  • MySQL慢查询定位与SQL性能优化实战教程
    如何定位并解决慢查询? 1. 开启/检查慢日志 看一下是否开启慢日志 1 2 3 SHOW VARIABLES LIKE slow_query_log; SHOW VARIABLES LIKE long_query_time; SHOW VARIAB
  • MYSQL的安装与介绍

    MYSQL的安装与介绍
    MySQL 是一款开源的关系型数据库管理系统(RDBMS),由瑞典 MySQL AB 公司开发,后被 Sun 收购,最终归属于 Oracle 公司。它以轻量、高性能、易
  • MySQL的REPLACE 函数用途与语句介绍

    MySQL的REPLACE 函数用途与语句介绍
    MySQL 的REPLACE有两个不同的用途,分别是: REPLACE()函数:用于字符串替换。 REPLACE INTO语句:用于插入或替换整行记录(类似INSERT INTO ... ON
  • Mysql表的内联和外联区别
    表的连接分为内连和外连 内连接 内连接实际上就是利用where子句对两种表形成的笛卡儿积进行筛选,我们前面文章的查询都是内连接,也是
  • MySQL CTE (Common Table Expressions)的介绍
    CTE (Common Table Expression,公共表表达式) 是 MySQL 8.0 引入的重要特性,它允许在查询中创建临时命名结果集,提高复杂查询的可读性和可维护性
  • SQL Server中的WITH(NOLOCK)介绍
    SQL Server 中的 WITH (NOLOCK) 详解 一、WITH (NOLOCK) 的本质 WITH (NOLOCK) 是 SQL Server 中的表提示(Table Hint),等同于 READUNCOMMITTED 隔离级别,它指示 SQ
  • MySQL强制使用特定索引的操作
    在MySQL中,你可以通过多种方式强制查询使用特定的索引,这在优化查询性能时非常有用,特别是当查询优化器没有选择最佳索引时。 1. 使
  • Navicat数据表的数据添加,删除及使用sql完成数据的

    Navicat数据表的数据添加,删除及使用sql完成数据的
    Navicat数据表数据添加,删除及使用sql完成数据添加 选中操作的表 右击----打开表(或者直接双击也行) 则出现如下界面,查看左下角 从左到右
  • 从入门到精通MySQL数据库索引(实战案例)
    一、索引是什么?能干嘛? 类比理解:索引就像书的目录。比如你想查《哈利波特》中 伏地魔 出现的页数,不用逐页翻书,直接看目录找
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计