mysql事务
一 事务简介
1 事务的4个特性
A 原子性: 转账的过程要不转成功,要不转失败,不存在转一半的情况
C 隔离性: 分两次转账,两次转账之间不能干扰对方
I 一致性: 用户账户中余额=收入 - 支出,等式成立
D 持久性: 数据修改保存后,不会进行回滚
2 事务的语法
1)开启事务
start transaction; 默认使用的是读写模式
2)提交事务
commit;
3)回滚事务
rollback;
3 自动提交
mysql中有个自动提交的系统变量autocommit, 默认值为ON开启,任何一条写操作都是自动开启事务、自动提交事务,如果想让几个写操作放在一个事务中,解决办法为使用start transaction 手动开启事务。
4 支持事务的存储引擎
innodb 常用
ndb 不常用,可以不深入研究
二 事务的隔离级别
1 四种隔离级别
read uncommited 未提交读
read commited 提交读
repeatable commited 可重复读
SERIALIZABLE 可串行
2 每种隔离级别对异常问题的支持情况
脏读: 修改未提交,其他事务也能读取到数据
不可重复读: 一个事务a 修改某条数据,另一个事务b 第一次读取该数据的值,和被事务a修改后读取该值不同(强调的是同一个数据修改前后读取不一样)
幻读: 一个事务a 开始读取满足条件的记录数为 x, 另一个事务之后插入了一条记录, 事务a提交前再次读取记录数变成 x+1 (强调是插入新数据前后读取的数据量不同)
三 MVCC
https://blog.csdn.net/qq_38538733/article/details/88902979
1 简介
事务的隔离级别如果使用read commited 、repeatable commited,当出现并发事务时,通过mvcc来控制版本数据的读取。
行记录中有2个隐藏列,trx_id事务id、rull_pointer回滚指针。
trx_id事务id记录了当前修改数据的事务id
undo日志中会保存记录每个事务版本的数据,rull_pointer通过找到undo中对应事务版本数据来实现回滚
版本链: undo中会保存记录每个版本的数据,并把这些版本数据串联成一个版本链,最新修改的数据放到链的头部。
ReadView: 记录当前活跃事务的id列表
2 repeatable commited如何实现mvcc
步骤如下:
-
新开启一个事务查询数据都会快照一份ReadView, ReadView中存着当前正在活跃的事务id,当前事务后续数据的读取都是使用同一份ReadView
-
查询数据时会从版本链中查看,如果版本数据的事务id在ReadView中则不可读,继续向下读取,找到非ReadView的事务id数据, 这种数据是可读的,如果查询的事务id比当前事务id还大,说明是在之后生成的事务,对当前事务来说也是不可读。