mysql事务超全~

大家好,我是程序媛雪儿,今儿咱聊聊mysql事务。

咱们先看一下什么是事务。

事务是什么

事务是一组操作的集合,是一个不可分割的工作单位,事务会把所有的操作作为一个整体向系统提交或者撤销操作,也就是说,这些操作要么同时成功,要么同时失败。

特性(ACID)

原子性(Atomicity):事务是不可分割的最小操作单元(要么都成功,要么都失败)

一致性(Consistency):事务完成时,必须使所有数据保持一致

隔离性(Isolation):数据库提供隔离机制,保证事务不受外部并发操作影响,在一个独立环境下运行

持久性(Durability):事务一旦提交或回滚,对数据库的改变是永久的,也就是说会保存到磁盘上

并发事务问题

有哪些

脏读

一个事务读到另外一个事务还没有提交的数据

事务A更新完数据还没提交,事务B此时读到了A还没提交的数据

不可重复读

一个事务先后读取同一条记录,但两次读取的数据不同

事务A第一次读到的是旧数据,第二次读这个数据前,这个数据已经被事务B改了,所以事务A第二次读到的数据和第一次读到的同一条数据不一样

幻读

一个事务按照条件查询数据的时候,没有对应的数据,但是在插入数据的时候,又发现这行数据已经存在了,好像出现了幻影

当事务A查数据库,发现id为1的数据没有,此时事务B把id为1的数据已经插入到数据库中,事务A再插入id为1的数据报错,再查id为1的数据,还是没有(因为解决了不可重复读,保证了两次数据一致)

解决方案

|----------|----|-------|----|
| 隔离级别 | 脏读 | 不可重复读 | 幻读 |
| 未提交读 | √ | √ | √ |
| 读已提交 | × | √ | √ |
| 可重复读(默认) | × | × | √ |
| 串行化 | × | × | × |

注:事务隔离级别越往下安全性越高,但是性能越差

事务的隔离级别是如何实现的?

本质还是老两套

锁:排他锁(一个事务获得了某一行,其他事务就不能再获取该行的锁了)

mvcc:多版本并发控制

什么是MVCC?

维护一个数据的多个版本,使得读写操作没有冲突

来看下面这个例子

MVCC的实现,主要依赖数据库记录中的隐式字段、undo log日志、readView

隐藏字段

|-------------|-------------------------|
| 隐藏字段 | 含义 |
| DB_TRX_ID | 最近修改事务ID,最后修改这条记录的事务ID |
| DB_ROLL_PTR | 回滚指针,指向是这条记录的上个版本 |
| DB_ROW_ID | 隐藏主键,表结构中如果没有主键就会生成这个字段 |

undo log日志中的版本链

事务对同一条记录修改,就会生成记录版本链,链表头部是最新的数据记录,尾部是最老的数据记录

readview

readview是快照读SQL执行时提取数据的依据。

这里聊到了一个概念,快照读,我们先搞明白什么是当前读和快照读

当前读:读取的是记录的最新版本,并且保证其他并发事务不能修改当前的记录(加锁)

快照读:读取的是记录数据的可见版本,可能是历史数据(不加锁、非阻塞)

|----------------|-----------------------------|
| 字段 | 含义 |
| m_ids | 当前活跃的事务ID集合(活跃的事务指的是未提交的事务) |
| min_trx_id | 最小活跃事务ID |
| max_trx_id | 最大事务ID+1 |
| creator_trx_id | 当前事务ID,readview创建的事务ID |

访问规则

trx_id代表的当前事务,在undo log日志当中,会依次遍历DB_TRX_ID,去找第一个符合的版本数据返回给用户

不同的隔离级别,生成的readview不同

read committed (读已提交):每次执行快照读时生成readview

事务5中查询id为30的记录,根据访问规则+生成的readview,第一次查询读到的是事务2,第二次查询读到的是事务3

repeatable read(可重复读):仅在事务第一次执行快照读时生成readview,后续复用该readview,保证在一个事务中读到的版本是一样的

事务5中查询id为30的记录,根据访问规则+生成的readview,第一次读到的是事务2,第二次查询读到的还是事务2,因为复用的第一个ReadView。

欢迎大家关注我的微信公众号,程序媛雪儿,雪儿会在上面发布编程的知识碎片,也有雪儿博客地址,上面有详细系统的笔记,雪儿是全栈,但是公众号目前主要还是发后端的技术,以后可能也会涉及到一些前端的知识,我们下期见,拜拜~

相关推荐
小白学大数据12 分钟前
JavaScript重定向对网络爬虫的影响及处理
开发语言·javascript·数据库·爬虫
time never ceases33 分钟前
使用docker方式进行Oracle数据库的物理迁移(helowin/oracle_11g)
数据库·docker·oracle
Frank牛蛙36 分钟前
1.每日SQL----2024/11/7
数据库·sql
Ciderw38 分钟前
块存储、文件存储和对象存储详细介绍
网络·数据库·nvme·对象存储·存储·块存储·文件存储
薛晓刚39 分钟前
数据库优化指南:如何将基本功能运用到极致?
数据库
stars_User43 分钟前
MySQL数据库面试题(下)
数据库·mysql
Yaml41 小时前
智能化健身房管理:Spring Boot与Vue的创新解决方案
前端·spring boot·后端·mysql·vue·健身房管理
未来之窗软件服务1 小时前
sql速度优化多条合并为一条语句
数据库
山东布谷科技官方1 小时前
布谷直播源码部署服务器关于数据库配置的详细说明
运维·服务器·数据库·直播系统源码·直播源码·直播系统搭建·直播软件开发
yanwushu1 小时前
Xserver v1.4.2发布,支持自动重载 nginx 配置
mysql·nginx·php·个人开发·composer