MySQL事务分类与验证
MySQL事务分类与验证
ivansliMySQL事务特性
- 原子性
整个事务是不可分割的最小执行单元,要么全部成功,要么全部失败 - 一致性
总是从一个一致性状态转换到另一个一致状态(不存在中间态) - 隔离性
一个事务所做修改在最终提交前,对其他事务不可见 - 持久性
一旦事务提交,其修改会永久保存到数据库中
事务的隔离级别以及对应问题
事务分类
事务分类 | 描述 | 事务ID |
---|---|---|
读事务 | 整个事务中只有读操作,则一直是读事务 | 使用事务对象地址计算得到唯一事务ID,比较大的数值 |
读写事务 | 事务中遇到第一个更新语句升级为读写事务 | 分配全局唯一的读写事务ID |
两个问题
- 事务是在使用 begin / start transaction 时真正开启的吗?
- 读事务、读写事务分别在什么时候得到事务ID?
验证使用的MySQL版本与测试表
两个命令行工具
1 | SHOW ENGINE INNODB STATUS \G -- 查看当前innodb引擎的监控信息 |
开启读事务验证
小结:
- 读事务在遇到第一条读操作SQL语句时开启
- 获得一个很大的事务ID
其他知识点
- 读事务ID在某种情况下会被缓存起来
- 同一个session会话中,多个连续的读事务,获得的读事务ID一样
- 读事务ID不是系统全局唯一的读写事务ID,不会被记录到undo log中
开启读写事务验证
小结:
- 读写事务在遇到第一条写操作语句时开启
- 被分配一个比较小的全局事务ID
事务升级
事务没有分类时存在的问题
需要知道的:数据库读写操作比例大部分基本符合 8/2规律。
在以前的老版本,事务没有分为读事务、读写事务。那么:
- 每个SQL执行语句都是一个执行事务 (即使没有显式的使用事务声明语句)
- 每个事务都会占用一个系统全局唯一事务ID
- 事务视图拍快照时,记录的当前活跃事务数组中包含80%读操作事务ID
- 事务会分配额外的空间来处理一些逻辑
造成问题:
- 读操作占用大量全局事务ID(全局ID的损耗)
- 活跃事务数组包含大量无用读操作事务ID(空间损耗)
- 判断可见性时,需要遍历大量无用读事务ID(计算性能损耗)
事务分类后的好处
事务分类的好处:
- 读事务不再占用全局事务ID (多个连续的读事务可以共用同一个读事务ID)
- 活跃事务列表中只有读写事务ID (减小了活跃事务数组的长度)
- 判断可见性时,只遍历少量读写事务ID (减小遍历时的性能损耗)
- 读事务不再分配额外的空间 (减小空间占用)