一、MySQL都有什么锁。

锁分类

按锁的粒度划分

行锁

开销大,加锁慢,会出现死锁,并发性能高。InnoDB支持,MyISAM不支持。

表锁

开销小,加锁快,不会出现死锁,并发性能低。

页锁

介于行锁和表锁之间的一种锁,会出现死锁,并发性能一般。

按锁的使用方式划分

共享锁

加上共享锁后,只能执行读操作,其他事务也只能对其加共享锁,不能加排它锁。

排他锁

加上排他锁后,其他事务不能读也不能写更不能加任何锁。

按思想上划分

悲观锁

基于MySQL自身的锁机制实现。

乐观锁

基于开发者实现,常用版本号实现。

二、常见死锁原因。

1、事务之间对资源访问顺序的交替

        两个用户同时执行一个操作,需要先后访问AB两个表,然后双方各锁住了一个表,互相等待对方释放锁。一般是程序逻辑出现问题会出现这种问题,解决方案是跳转逻辑。

2、并发修改同一个记录

        用户A查询一条纪录,然后修改该条纪录;这时用户B修改该条纪录,这时用户A的事务里锁的性质由查询的共享锁企图上升到独占锁,而用户B里的独占锁由于A有共享锁存在所以必须等A释放掉共享锁,而A由于B的独占锁而无法上升的独占锁也就不可能释放共享锁,于是出现了死锁。这种情况的解决方案一般是用乐观锁去解决,一般是使用版本号去检查。

3、索引不当导致全部扫描

        表中的数据量非常庞大而索引建的过少或不合适的时候,使得经常发生全表扫描,最终应用系统会越来越慢,最终发生阻塞或死锁。解决方案是利用执行计划优化查询的SQL。

4、事务封锁范围大且相互等待

        事务运行时间越长,其持有排它锁或更新锁的时间也就越长,从而堵塞了其它活动并可能导致死锁。

四、产生死锁的四个必要条件

(1) 互斥条件:一个资源每次只能被一个进程使用。
(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
(3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
(4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

五、解开死锁的两种方式

(1) 剥夺资源:从其它进程剥夺足够的资源给死锁进程好让其顺利执行;
(2) 撤销进程:在产生死锁的时候可以采取剥夺代价最小的进程,好让另外的进程顺利执行。