3、由于禁用了间隙锁定 , 因此可能会产生幻影行问题,因为其他会话可以在间隙中插入新行 。
4、 对于[ UPDATE ]或 [ DELETE ]语句,InnoDB 仅对其更新或删除的行持有锁 。MySQL评估 WHERE 条件后,将释放不匹配行的记录锁。这大大降低了死锁的可能性,但是仍然可以发生 。
5、对于[ UPDATE ]语句,如果某行已被锁定,则 InnoDB执行“半一致”读取,将最新提交版本的数据返回给MySQL , 以便MySQL可以确定该行是否符合WHERE 条件 。如果该行匹配(必须更新),则MySQL会再次读取该行,这一次 InnoDB 会将其锁定或等待获取锁 。
6、注意
从MySQL 8.0.22开始,DML操作(增删改,通过联接列表或子查询)从MySQL授权表中读取数据,但不对其进行修改,无论隔离级别如何,都不会在MySQL授权表上获得读取锁 。
有关更多信息,请参见Grant Table Concurrency。
四、乐观锁与悲观锁
1、乐观锁
在UPDATE的WHERE子句中加入版本信息来确定修改是否生效
使用乐观锁时仍然需要非常谨慎 , 因为RR是可重复读的,在UPDATE之前读取版本号 , 应该使用[当前读],不能使用[快照读]
2、悲观锁
在UPDATE执行前,SELECT后面加上FOR UPDATE来给记录加锁,保证记录在UPDATE前不被修改 。SELECT ... FOR UPDATE是加上了X锁,也可以通过SELECT ... LOCK IN SHARE MODE加上S锁,来防止其他事务对该行的修改 。
3、无论是乐观锁还是悲观锁,使用的思想都是一致的,那就是当前读 。乐观锁利用当前读判断是否是最新版本,悲观锁利用当前读锁定行 。
五、总结
1、RC级别没有范围锁一定会导致不可重复读和幻影行
2、RR级别安全性更高 , 实现可重复读的方式为快照,如果需要最新数据可以选择[当前读],因此RR级别是首选
3、不论RR还是RC级别,增、删、改的操作都会进行一次[当前读]操作,以此获取最新版本的数据 , 并检测是否有重复的索引 。
4、RR级别下,当前事务如果未发生更新操作(增删改) , 快照版本会保持不变,多次查询读取的快照是同一个
5、RR级别下,当前事务如果发生更新(增删改),会刷新快照,会导致不可重复读和幻影行
6、RR级别下,使用当前读,会刷新快照,会导致不可重复读和幻影行
7、RR级别下 , 可以通过提交当前事务并在此之后发出新查询来为查询获取更新的快照 。
8、RR级别可以部分解决不可重复读和幻读问题
9、其实问题的关键是你的业务逻辑需要可重复读还是最新数据
mysql 解决可提交读、可重复读、幻读这张图本人觉得总结得挺好的 , 在一般的互联网项目中,基本上用的都是Innodb引擎,一般只涉及到的都是行级锁,但是如果sql语句中不带索引进行操作,可能会导致锁表,这是不推荐的,性能非常低 , 可能会导致全表扫描等,行锁的具体实现算法有以下几种mysql特有的锁:
Record Lock(记录锁):单个行记录的锁,一般是唯一索引或者主键上的加锁
Gap Lock(间隙锁):锁定一个区间 , 但是不包括自身,开区间的锁,RR级别才会有间隙锁 , 间隙锁的唯一目的是防止区间数据的插入,所以间隙锁与间隙锁之间是不会相互阻塞的
Next-key Lock(临键锁):与间隙锁的区别是包括自身,是左开右闭区间,RR级别才会有
加锁规则里面,包含了两个“原则”、两个“优化”和一个“bug” 。
原则 1:加锁的基本单位是 next-key lock , 希望你还记得 , next-key lock 是前开后闭区间 。
- mysql游标和存储过程是什么 mysql游标表名为变量
- 如何使用cmd命令行提示符登录mysql服务器 cmd中登陆mysql
- mysql怎么设置时区 mysql时间显示设置
- 招聘要精通mysql
- mysql 65535 8192 限制 mysql限制资源使用
- mysql有topn
- mysql协议包解析 mysqlicp协议
- mysql子查询和连接查询 mysql子查询插入
- Mysql使用索引查询 mysql使用round
- 云服务器游戏出现黑屏问题怎么解决? 云服务器游戏黑屏怎么办
