行锁
针对数据表中行记录的锁 - 事务A更新了一行,而事务B更新同一行,则必须等事务A的操作完成后才能进行更新。
MyLSAM引擎不支持行锁意味着并发控制只能使用表锁。 InnoDB引擎是支持行锁的。
两阶段锁
两阶段锁,锁的添加与释放分到两个阶段进行,之间不允许交叉加锁和释放锁。 也就是在事务开始执行后为涉及到的行按照需要加锁,但执行完不会马上释放,而是在事务结束时再统一释放他们。
注意注意注意
- 如果个人的事务中要锁多个行,把最可能造成锁冲突、最可能影响并发度的锁尽量后放
以下操作:
- 从顾客A账户余额中扣除电影票价
- 给影院B的账户余额增加这张电影票价
- 记录一条交易日志
要完成这个交易: update两条数据,insert一条记录。为了保证交易的原子性,将三个操作放在一个事务。
问题一: 另外一个顾客C要在B买票,那么两个数据都在更新同一个影院的余额。
根据两阶段锁协议, 3 1 2的顺序,最后一个锁时间就最少因为它在事务提交前完成。
循环等待死锁
涉及的线程都在等待别的线程释放资源时,就会导致几个线程都进入无限等待的状态 成为死锁。
死锁检测要消耗大量的CPU资源
解决方法: 1.设置超时时间 innodb_lock_wait_timeout 2.开始死锁检测的变量innodb_deadlock_detect; show variables like 'innodb_deadlock_detect';
热点行更新的解决策略:降低并发度
-
一行拆多行(抑制目标源) -> 总的银行存款和分为多个行之和
-
Server层限流(目标分散化) -> 同一时间进入更新的线程数
-
关闭死锁检测(无视问题)