MySQL学习笔记之行锁(七)
声明:本文章内容是根据极客时间中林晓斌的课程《MYSQL45讲》,经过学习,加以自己的理解形成的笔记。具体原文可以到官网进行阅读。如有侵权请,告知删除。
1.行锁
MySQL的行锁是在引擎层由各个引擎实现的,MyISAM引擎不支持行锁。不支持行锁,那么也就是说他的并发控制只能用表锁、这种锁的粒度比较大,不适合业务的发展,这也就是 InnoDB引擎的巨大优势所在,支持行锁。
2.两段锁
当事务B
执行更新的时候,显然是会被阻塞的,因为在次之前执行了更新语句,获得了 id=1,和id=2这个数据的行锁。必须等释放之后,事务B才能继续执行,因为不同事务的行锁死互斥的,不能同时获得。那么也就可以说明在InnoDB事务中,行锁死需要的时候才加上,并不是不需要就立马释放,而是要等事务结束的时候才释放。这个就是两段锁协议
事例: 模拟转账
1.小A 转 出100元到 小B‘ 执行操作: 小A账户金额减去 100
2.小B 收到 100元 执行操作:小B账户金额加上100
3.银行记录一条交易日志 执行操作:inner一条交易日志
这三个操作肯定是放在一个事务当中,那么执行的顺序,怎么安排才合理呢。假如情景:小B经常会收到转账金额。那么步骤2存在并发问题。那么并发加锁的时候,会出现锁等待,为了进一步提高业务的执行, 可以安排逻辑步骤为 1,3,2.可以保证最高的效率。总结来说也就是:如果你的事务中需要锁多个行,要把最可能造成锁冲突、最可能影响并发度的锁尽量往后放。
死锁和死锁检测
什么是死锁:就是两个或两个以上的进程,在等待对方所占有的资源,从而导致程序无法运行下去。而MySQL当中的死锁,可以理解为 锁就是一种资源 相互等待对方所拥有的锁,导致一直等待的现象就是死锁
事务A与事务B 就出现了死锁。
出现死锁有两种策略
- 一种策略是,直接进入等待,直到超时。这个超时时间可以通过参数 innodb_lock_wait_timeout 来设置
- 另一种策略是,发起死锁检测,发现死锁后,主动回滚死锁链条中的某一个事务,让其他事务得以继续执行。将参数 innodb_deadlock_detect 设置为 on,表示开启这个逻辑。
使用innodb_lock_wait_timeout
如果设置的过小很容误伤;采用第二种方式innodb_deadlock_detect
他的默认值本身就是on