MYSQL幻读

当前读:update、delete、insert、select …from for update;读取最新的数据
快照度:select查询。根据MVCC读取对应版本数据。

有表student,字段有id、name,现有数据如下:

idname
1张三
2李四

有两个事务A和B。操作过程如下:
1.A事务开启:BEGIN
2.A事务查询 :SELECT * FROM student,查到id为1和2两条数据
3.B事务开启:BEGIN
4.B事务插入数据:INSERT INTO student(id, name) VALUES (3, ‘王五’);

5.B事务提交:COMMIT;
6.A事务再次查询 :SELECT * FROM student,仍然只能查到id为1和2两条数据(RR可重复读)
7.A事务插入数据:INSERT INTO student(id, name) VALUES (3, ‘王五’);报错:Duplicate entry ‘3’ for key ‘PRIMARY’。产生了幻读。

分析:因为INSERT是当前读,所以会拿到表中最新的数据,而此时id=3的数据已经存在了。所以会插入失败。

如何解决:行锁 + 间隙锁
1.A事务开启:BEGIN
2.A事务查询 :SELECT * FROM student WHERE id = 3 for update,该语句开启了行锁,会把id = 3这行锁住。
3.B事务开启:BEGIN
4.B事务插入数据:INSERT INTO student(id, name) VALUES (3, ‘王五’); 插入操作会被锁住,直到事务A回滚或提交。

InnoDB的行锁是针对索引加的锁,不是针对记录加的锁。并且该索引不能失效,否则都会从行锁升级为表锁。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值