不少人在开发的时候,应该很少会注意到这些锁的问题,也很少会给程序加锁(除了库存这些对数量准确性要求极高的情况下),即使我们不会这些锁知识,我们的程序在一般情况下还是可以跑得好好的。因为数据库隐式帮我们加了这些锁了,只有在某些特定的场景下我们才需要手动加锁。
对于UPDATE、DELETE、INSERT语句,InnoDB会自动给涉及数据集加排他锁(X) 。而MyISAM在执行查询语句SELECT前,会自动给涉及的所有表加读锁,在执行增、删、改操作前,会自动给涉及的表加写锁,这个过程并不需要我们去手动操作。
那么在特定情况下,我们该如何去加锁呢?下面咱们来认真的看看
看上图就知道MySQL锁可以按使用方式分为:乐观锁与悲观锁。按粒度分可以分为表级锁,行级锁,页级锁。
表锁
从锁的粒度,我们可以分成两大类:
表锁: 开销小,加锁快;不会出现死锁;锁定力度大,发生锁冲突概率高,并发度最低。
行锁: 开销大,加锁慢;会出现死锁;锁定粒度小,发生锁冲突的概率低,并发度高 不同的存储引擎支持的锁粒度是不一样的。
InnoDB行锁和表锁都支持、MyISAM只支持表锁!
InnoDB只有通过索引条件检索数据才使用行级锁,否则,InnoDB使用表锁也就是说,InnoDB的行锁是基于索引的!
表锁下又分为两种模式: 表读锁(Table Read Lock)&& 表写锁(Table Write Lock)
从下图可以清晰看到,在表读锁和表写锁的环境下:读读不阻塞,读写阻塞,写写阻塞!
读读不阻塞: 当前用户在读数据,其他的用户也在读数据,不会加锁
读写阻塞: 当前用户在读数据,其他的用户不能修改当前用户读的数据,会加锁!
写写阻塞: 当前用户在修改数据,其他的用户不能修改当前用户正在修改的数据,会加锁!