生产环境的MySQL事务隔离级别方式

 更新时间:2025年02月07日 15:49:14   作者:空说  
本文探讨了MySQL数据库在RR(可重复读)和RC(读已提交)隔离级别下的锁机制,在RR级别下,UPDATE语句会锁定所有符合条件的行,包括不符合条件的行,以防止幻读,而在RC级别下,UPDATE语句仅锁定符合条件的行,通过半一致性读优化,可以进一步提高并发度

生产环境的MySQL事务隔离级别

MySQL 数据库的默认隔离级别是 RR( 可重复读 ),但是很多大公司把隔离级别改成了 RC(读已提交),主要原因是为了提高并发和降低死锁概率

为了解决幻读的问题 RR 相比 RC 多了间隙锁( gap lock )和临键锁( next-keylock )。而 RC 中修改数据仅用行锁,锁定的范围更小,因此相比而言 RC的并发更高。

创建如下的表,并插入一些记录

CREATE TABLE t (a INT NOT NULL, b INT) ENGINE = InnoDB;
INSERT INTO t VALUES (1,2),(2,3),(3,2),(4,3),(5,2);

此时执行SQL-A ,且未提交事务

UPDATE t SET b = 5 WHERE b = 3;

在 RR 即可重复隔离级别情况下,会锁哪几条数据呢?

答案是会锁定所有符合条件的行,并且为了防止幻读,还会锁定这些行之间的间隙。

x-lock(2,3) 和 x-lock(4,3)  -- 这两行会被更新并保留X锁。
x-lock(1,2)、x-lock(3,2) 和 x-lock(5,2) -- 这些行虽然不符合更新条件,但由于间隙锁的存在,它们也会被锁定以防止其他事务插入新的行

可以看到全锁了,此时执行 SQL-B:

UPDATE t SET b = 4 WHERE b = 2;

就会被阻塞了。

因此,在RR隔离级别下,UPDATE t SET b = 5 WHERE b = 3; 会锁定所有行,包括那些不符合更新条件的行。

而执行 SQL-A 在 RC 即读已提交隔离级别下,会锁哪几条数据呢?

x-lock(1,2); unlock(1,2)
x-lock(2,3); update(2,3) to (2,5); 保留 x-lock
x-lock(3,2); unlock(3,2)
x-lock(4,3); update(4,3) to (4,5); 保留 x-lock
x-lock(5,2); unlock(5,2)
-- 只会锁定符合更新条件的行,即 b = 3 的行,因为RC级别不使用间隙锁。

可以看到,只锁了两条数据,此时执行 SQL-B 会怎样?

x-lock(1,2); update(1,2) to (1,4); 保留 x-lock
x-lock(2,3); unlock(2,3)
x-lock(3,2); update(3,2) to (3,4); 保留 x-lock
x-lock(4,3); unlock(4,3)
x-lock(5,2); update(5,2) to (5,4); 保留 x-lock

可以看到仅锁了 b=2 的数据,完美避开了 SQL-A加的锁

此时可能有同学会有疑问: SQL-B 不是应该被 (2, 3 )这行的锁给阻塞吗?

半一致性读(“semi-consistent”read)

这其实也是 InnoDB 做的一个优化。

  • 在执行 update 的时候,扫描发现当前行已经被锁定了,它就会执行半一致性读的操作,得到当前数据的最新版本(上述中 SQL-A 锁定的行最新版本的已提交数据,b都为5 ),来判断是否和当前的(SQL-B)update 的 where 条件匹配
  • 如果匹配则说明当前的 update也需要锁定这行
  • 因此需要等待。如果不匹配说明它们之间没关联,因此不需要等待锁,这个优化提升了并发度。

所以 RC + 半一致性读 能进一步的提升 SQL 执行的并发度。

并且 RC 锁的粒度更小,意味着死锁的概率会更低,但是缺点是可能会产生幻读,这个就需要业务自已评估幻读的问题(大部分情况下都没啥影响)。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • MySQL中binlog+dump备份还原详细教程

    MySQL中binlog+dump备份还原详细教程

    MySQL备份是指将MySQL数据库中的数据进行备份,以便在需要的时候能够恢复数据,下面这篇文章主要给大家介绍了关于MySQL中binlog+dump备份还原的相关资料,需要的朋友可以参考下
    2023-05-05
  • MySQL数据库的一次死锁实例分析

    MySQL数据库的一次死锁实例分析

    本文主要给大家通过一个实例来具体介绍MySQL死锁问题的相关知识,接下来我们就来一一介绍这部分内容,希望能够对您有所帮助。
    2016-11-11
  • 详解windows下mysql的主从同步

    详解windows下mysql的主从同步

    本文主要对windows下的mysql主从同步进行详细介绍。具有很好的参考价值,需要的朋友一起来看下吧
    2016-12-12
  • MySQL报错sql_mode=only_full_group_by的问题解决

    MySQL报错sql_mode=only_full_group_by的问题解决

    本文主要介绍了MySQL报错sql_mode=only_full_group_by的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-02-02
  • mysql使用from与join两表查询的区别总结

    mysql使用from与join两表查询的区别总结

    这篇文章主要给大家介绍了关于mysql使用from与join两表查询的区别的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-12-12
  • Linux如何添加mysql系统环境变量

    Linux如何添加mysql系统环境变量

    这篇文章主要介绍了Linux如何添加mysql系统环境变量问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04
  • mysql安装时出现各种常见问题的解决方法

    mysql安装时出现各种常见问题的解决方法

    mysql数据库安装不了了!mysql最后一步安装不上?真头疼!这篇文章主要为大家详细介绍了解决mysql安装时出现各种经典问题的方法,感兴趣的小伙伴们可以参考一下
    2016-08-08
  • MySQL每日一练项目之校园教务系统

    MySQL每日一练项目之校园教务系统

    这篇文章主要给大家介绍了关于MySQL每日一练项目之校园教务系统的相关资料,教务管理系统是一套高校专用管理系统,主要用于解决信息化办公流程、学生管理、课程管理、教职工管理等相关问题,需要的朋友可以参考下
    2023-09-09
  • Mysql的Binlog数据恢复:不小心删除数据库详解

    Mysql的Binlog数据恢复:不小心删除数据库详解

    这篇文章主要介绍了Mysql的Binlog数据恢复,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • 将MySQL数据库移植为PostgreSQL

    将MySQL数据库移植为PostgreSQL

    PostgreSQL 作为功能最强劲的开源 OO 数据库,仿佛一直不为国内用户所熟识。而我个人也仅是因为工作的缘故接触到这款超经典的数据库,并深为之折服。
    2009-07-07

最新评论