mysql事务隔离机制和解决不可重复读幻读个人总结

事务隔离级别脏读不可重复读幻读
读未提交(read-uncommitted)可能可能可能
读已提交(read-committed)不可能可能可能
可重复读(repeatable-read)不可能不可能可能
串行化(serializable)不可能不可能不可能

1、脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据

2、不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果不一致。(修改、删除)

3、幻读:事务 A 多次读取同一数据,事务B插入一条数据,事务B读到新插入的数据,结果不一致,这就叫幻读。(插入)

解决可重复读:mvcc机制主要由两个隐式字段DB_TRX_ID、DB_ROLL_PTR),readviewundo日志实现。

隐式字段

  • DB_TRX_ID:记录最后一次修改该记录的事务id。当每个事务执行修改记录时,都会被分配一个ID, 这个ID是递增的
  • DB_ROLL_PTR:回滚指针,指向当前记录的最新历史版本。

Read View:就是事务首次快照读操作的时候产生的读视图主要由当前未提交事务ID数组、未提交事务ID数组最小值(up_limit_id)所有事务ID的最大值+1(low_limit_id)三部分组成。用于可见性判断,查询的结果集根据readview做比对生成快照。

比对规则:

  1. 首先比较DB_TRX_ID < up_limit_id, 如果小于,则当前事务能看到DB_TRX_ID 所在的记录,如果大于等于进入下一个判断
  2. 接下来判断 DB_TRX_ID 大于等于 low_limit_id , 如果大于等于则代表DB_TRX_ID 所在的记录在Read View生成后才出现的,那对当前事务肯定不可见,如果小于则进入下一个判断
  3. 判断DB_TRX_ID 是否在活跃事务之中,trx_list.contains(DB_TRX_ID),如果在,则代表我Read View生成时刻,你这个事务还在活跃,还没有Commit,你修改的数据,我当前事务不可见,当前自己事务的修改可见;如果不在,则说明,你这个事务在Read View生成之前就已经Commit了,可见
  4. 删除是修改的特殊情况,也会加入undo日志,修改DB_TRX_ID,同时在该记录的头信息(record header)里(deleted flag)标记位写上true,查询遵循以上规则,并将忽略标记位为true的记录。

undo日志:一条历史记录链,链首就是最新的旧记录,链尾就是最早的旧记录。

:RC级别每次快照读都生成readview,RR级别首次执行快照读时生成,并之后一直沿用。

快照遵循规则:当前事务内的更新,可以读到;版本未提交,不能读到;版本已提交,但是却在快照创建后提交的,不能读到;版本已提交,且是在快照创建前提交的,可以读到。


聚集索引:主键索引
二级索引:非主键索引的索引

解决幻读临键锁(!=行锁+间隙锁)
当检索条件为聚集索引时并且不在间隙锁(左开右开)范围内,会在索引树上定位行,只加上行锁,否则,只加间隙锁。
当检索条件为二级索引时并且不在间隙锁范围内,会加上行锁,并在二级索引左边和右边都加上临键锁(左闭右开),否则,只加临键锁

当检索条件不为索引时,数据库会为整个表加上间隙锁和行锁。
加上行锁后,MySQL 会进行一遍过滤,发现不满足的行就释放锁,最终只留下符合条件的行。虽然最终只为符合条件的行加了锁,但是这一锁一释放的过程对性能也是影响极大的。

:临键锁间隙锁是在对应区间内不能插入数据,行锁是不能修改对应行数据。

参考链接https://blog.csdn.net/SnailMann/article/details/94724197

                  https://baijiahao.baidu.com/s?id=1662096005584873447&wfr=spider&for=pc

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值