【MySQL篇】MySQL的MVCC是什么😵‍💫,解释清楚什么是脏读、不可重复读、幻读

各种非正常读

脏读

事务A读取到了事务B还未提交的数据,被称之为脏读。

不可重复读

在并发更新操作时,在同一次事务中,前后两次查询到的数据是不一样的。

幻读

在并发新增、修改时,在同一次事务中,前后两次查询到的数据量不一致。用户产生不可预料的问题


事务隔离级别

可以解决脏读、幻读、不可重复读的问题。

隔离级别 隔离级别英文 脏读 幻读 不可重复读 加锁读 说明
读未提交 Read UnCommitted (RU) 是 是 是 否 能够读取到其它事物未提交的内容
读已提交 Read Committed (RC) 否 是 是 否 只能读取到其它事物提交成功的内容
可重复读 Repeatable Read (RR) 否 否 innoDB除外 是 否 读取某行后,不允许其它事物操作此行,直到事物结束
序列化 Serializable 否 否 否 是 等待其它事物执行完成后,依次执行,性能低,安全性高

MVCC并发版本控制

MVCC全称(Multiversion Concurrency Control)

在MySQL的InnoDB引擎下,RC、RR基于MVCC(多版本并发控制)进行并发事务控制,MVCC是基于数据版本来进行并发事务访问的一种技术。

RR在MVCC下不能保证不产生幻读的问题。因为如果在两次快照读中间穿插了当前读,那么ReadView会被重新生成,因此可能会导致幻读的问题产生。既第一次读到了3条数据,第二次读到了2条数据。

UNDO_LOG

UNDO_LOG(回滚日志)版本链条

MySQL会在确定UNDO_LOG没有其它事务引用时才会删除。

ReadView

ReadView就是快照读SQL执行时,MVCC提取数据的依据。当前读不会使用MVCC。

  • 快照读:就是最基础的查询语句。使用MVCC。
  • 当前读:执行下列语句时读取数据的方式。使用行锁 + 间隙锁。
    • INSERT、UPDATE、DELETE
    • SELECT ... FOR UPDATE
    • SELECT ... LOCL IN SHARE MODE

ReadView属性

  • m_ids:当前活跃的事务id列表
    • 活跃:没有commit、rollback的事务
  • min_trx_id:最小活跃的事务id
  • max_trx_id:预分配的事务id,最大事务编号 +1
  • cerator_trx_id:ReadView创建者的事务编号

ReadView生成时机:

  • 读已提交RC:每次读取都会生成新的ReadView
  • 可重复读RR:会复用第一次生成的ReadView
    • 因为所使用的ReadView是一模一样的,所以RR是可重复读的。

ReadView提取数据的逻辑

ReadView会根据自己的属性,去到UNDO_LOG中提取数据,提取的顺序由UNDO_LOG的事务号从大到小依次读取,如果当前不满足,就会往下接着找,最终找到符合条件的数据。规则如下。

  • 判断当前事务id是否等于,ReadView创建者的事务id,如果是的话就说明这个事务是自己的,可以访问数据。
  • 判断trx_id < min_trx_id,自己的事务id是否小于最小的活跃事务id,如果是的话说明自己已经被提交了,可以访问。
  • 判断 trx_id > max_trx_id 如果自己的事务id大于ReadView生成时的最大事务ID,那么说明自己还没有提交。不可以访问。
  • 判断 min_trx_id <= trx_id <= max_trx_id,如果当前事务id大于等于最小事务id,并且小于等于预分配事务id,成立的话就去活跃的事务id列表中查找,没找到,说明自己被提交了,那就可以访问,否则就不可以访问。

参考地址:IT老齐


Spring事务

三方操作如何保证原子性

在开发业务的过程中,往往可能遇到这种场景,在数据库事务操作完毕后,给第三方组件、服务发送一条消息、HTTP请求。像这种操作如果直接写在事务内部,则有可能会影响主要业务代码的运行,如果写在外部,则无法保证事务操作与三方操作的原子性。

在Spring中提供了一个功能,事务回调接口

相关推荐
子兮曰3 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰3 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
爱勇宝3 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
胡写代码3 天前
别再前后端各写一套表单校验了
java·后端
大勇前进3 天前
原生 PHP 还是 Laravel?小项目到底要不要上框架
后端
yuzhi_liu3 天前
我用 LangGraph4j 实现 Multi-Agent Supervisor
后端
alsmile3 天前
Node-RED 之外,国产规则引擎的新方案:基于标准语法,Go 先行实现
后端·开源·go
大白803 天前
PHP 内存溢出排查思路:看懂报错日志,精准定位问题
后端
二月龙3 天前
PHP 接口返回统一响应封装,让前后端对接更省心
后端
盖伦发发3 天前
软件工程SOLID 五大设计原则
后端·软件工程