InnoDB|S 锁与 X 锁的爱恨情仇《死磕MySQL系列 四》

InnoDB|S 锁与 X 锁的爱恨情仇《死磕MySQL系列 四》

文章图片

InnoDB|S 锁与 X 锁的爱恨情仇《死磕MySQL系列 四》

文章图片

InnoDB|S 锁与 X 锁的爱恨情仇《死磕MySQL系列 四》

文章图片


系列文章一、原来一条select语句在MySQL是这样执行的《死磕MySQL系列 一》
二、一生挚友redo log、binlog《死磕MySQL系列 二》
三、MySQL强人“锁”难《死磕MySQL系列 三》
获取MySQL各种学习资料
前言下边两幅图还熟悉吧!就是第三期文章中的前言 , 但上一期文章并未提及死锁 , 只是引出了全局锁、表锁的概念 。 本期文章将继续聊聊锁的内容 。
Lock wait timeout exceeded; try restarting transaction

Deadlock found when trying to get lock; try restarting transaction

一、行锁行锁的锁粒度最小 , 发送锁冲突的概率最低 , 并发度也最高 。
问题:MySQL的所有存储引擎都支持行锁吗?
不是的 , MySQL中只有Innodb存储引擎才支持行锁 , 其它的并不支持 , MyIsam存储引擎也只支持表锁 。
所以Myisam存储引擎只能使用表锁来解决并发 , 表锁开销小 , 加锁快 , 锁定粒度大 , 发生锁冲突的概率最高 , 并发度最低 。
问题:锁粒度指的是什么?
这种名词不能只记名字 , 需要知道其代表的含义 。 锁粒度指的是加锁的范围 。
上期文章讲的全局锁锁的是整库、表锁锁定的全表、行锁指的是锁定某一行或某个范围的数据 。
问题:如何加行锁?
Innodb存储引擎在执行update、delete、insert语句时会隐式加排它锁 , 而对于select不会加任何锁 。
同样也可以手动加锁 。
共享锁:select * from tableName where id = 100 lock in share more
排它锁:select * from tableName where id = 100 for update
共享锁、排它锁也被称之为读锁、写锁 。 读锁与读锁之间不互斥 , 读锁与写锁、写锁与写锁之间是互斥的 。
问题:为什么要加锁?
MySQL事务的四大特性分别是原子性、隔离性、一致性、持久性 , 当你了解完事务的四大特性之后就发现都是为了保证数据一致性为最终目的的 。
常说一句话有人地方就有江湖 , 放在MySQL中是有锁的地方就有事务 。
所以说加锁就是为了保证当事务结束后 , 数据库的完整性约束不被破坏 , 从而确保数据一致性 。
二、两阶段锁问题:两阶段锁是什么?
说实话 , 这个名字属实很唬人 , 猛然间你有没有想到另一个名词两阶段提交 。 这里回忆一下 , 两阶段提交是确保redo log跟binlog同时提交成功 , 若有一方提交失败则回滚 。