Mysql中的锁可以分为共享锁/读锁(Shared Locks)、排他锁/写锁(Exclusive Locks) 、间隙锁、行锁(Record Locks)、表锁。
从操作上来说分为:共享锁/读锁 , 排它锁/写锁,
1.共享锁/读锁 : 针对同一份数据,多个读操作可以同时进行,简单来说即读加锁,不能写并且可并行读;
2.排它锁/写锁: 当前写操作没有完成,那么它会阻断其它的写锁和读锁,即写加锁,其它读写都阻塞 。
从粒度上来说分为:行锁, 表锁
1.行锁:行锁锁定当前数据行,锁的粒度小,加锁慢,发生锁冲突的概率小,并发度高,行锁也是MyISAM和InnoDB的区别之一,InnoDB支持行锁并且支持事务 。
2.表锁:表锁则锁的粒度大,加锁快,开销小,但是锁冲突的概率大,并发度低。
什么是间隙锁?
间隙锁是一个在索引记录之间的间隙上的锁。
MySQL间隙锁
假如两个事务执行写操作,又怎么保证并发呢?
假如事务1和事务2都要执行update操作,事务1先update数据行的时候,先回获取行锁(这是在有索引的情况下【索引的优势】),锁定数据,当事务2要进行update操作的时候,也会取获取该数据行的行锁,但是已经被事务1占有,事务2只能wait。若是事务1长时间没有释放锁,事务2就会出现超时异常 。
而在没有索引的情况下, 就获取所有行,都加上行锁,然后Mysql会再次过滤符合条件的的行并释放锁,只有符合条件的行才会继续持有锁。这样的性能消耗也会比较大。
读未提交是不加锁的
对于读提交和可重复读,他们俩的实现是兼顾解决数据问题,然后又要有一定的并发行,所以在实现上锁机制会比串行化优化很多,提高并发性,所以性能也会比较好。
串行化:读的时候加 (读锁),不允许写; 写的时候加(写锁),不允许读和写,耗费性能
死锁产生的四个必要条件
- 互斥条件。一个资源只能被一个进程占用
- 不可剥夺条件。某个进程占用了资源,就只能他自己去释放。
- 请求和保持条件。某个进程之前申请了资源,我还想再申请资源,之前的资源还是我占用着,别人别想动。除非我自己不想用了,释放掉。
- 循环等待条件。一定会有一个环互相等待。