行锁
各个搜索引擎有自己的行锁实现方式。MyIsam没有实现行锁,这个是被innodb取代在原因之一。
innodb实现行锁基于索引,如果没有使用索引,innodb将锁住整个表。
两段锁协议:innodb不会在事务一开始就加行锁,而是在执行到对应的脚本时,才进行加行锁,并且在事务提交后才释放锁。
死锁与检测
由于资源的独占和循环等待释放,而进入无限等待的阶段。
解决:
方案1:设置innodb_lock_wait_timeout等待时间,等待超时就进行事务回滚。
方案2:发起死锁校验,innodb_deadlock_detect设置为on。当发现死锁时,进行事务回滚,以让其他事务正常执行。
方案1如果设置时间过长,将不能让程序接受,设置时间过断,会误伤部分正常的事务。
方案2比较推荐,但是死锁校验会有性能问题。比如有1000条事务进行死锁校验,那么校验的时间复杂度为o(n),也就是100w级别的。这个过程会大量消耗cup,但是却执行不了多少事务。优化方案:控制并发数,或者关闭死锁校验(危险)
思考题
如果你要删除一个表里面的前10000行数据,有以下三种方法可以做到:
- 第一种,直接执行delete from T limit 10000;
- 第二种,在一个连接中循环执行20次 delete from T limit 500;
- 第三种,在20个连接中同时执行delete from T limit 500。
答案:第二种方案
第一种方案事务时间太长,容易导致主从延迟,并且加锁时间也比较长。
第二种比较适合,
第三种方案认为制造冲突,除非加上特地过滤条件。