共享锁 又称为读锁,获得共享锁之后,可以查看但无法修改和删除数据。
排它锁 又称为写锁,独占锁。获得排它锁之后,既能读数据,又能修改数据。
锁,是用来解决并发问题的。为了避免多个事务同时操作数据库导致数据异常,一般会通过加锁的机制解决。
共享锁用法:在查询语句后边增加 LOCK IN SHARE MODE,MySQL会对查询结果中的每行都加共享锁。
当没有其他线程对结果集中的任何一行使用排他锁时,可以成功申请共享锁,否则会被阻塞。其他线程也可以读取使用了共享锁的表,而这些线程读取的是同一个版本的数据库。
排它锁用法:在查询语句后边增加FOR UPDATE,MySQL会对查询结果中的每行都加排它锁。
当没有其他线程对查询结果集中的任何一行使用排它锁时,可以成功申请排它锁,否则会被阻塞。
举例说明:卫生间可以用来洗脸,化妆,上厕所。每个卫生间都会有一把锁,防止自己方便时有人进来就不好了。
共享锁:当我们在卫生间进行化妆或者洗脸的时候,其他人也可以进来洗脸或者化妆,但是不能进来上厕所(除非你有特殊癖好)。
排它锁:当在卫生间进行上厕所时任何人都不能进来,不管是想要洗脸化妆还是上厕所。
加锁原则。
拿MySQL的innoDB引擎来说,对于insert,update,delete等操作,会自动给涉及的数据加排它锁。
对于一般的select语句,InnoDB不会加任何锁,事务可以通过以下语句给显示加共享锁或排它锁。
共享锁:select 。。。。LOCK IN SHARE MODE;
排它锁:select。。。。FOR UPDATE;
锁机制
在DBMS中,可以按照锁的粒度把数据库锁分为行级锁(INNODB引擎)、表级锁(MYISAM引擎)和页级锁(BDB引擎)。
行级锁:是MySQL中粒度最细的一种锁,表示只是针对当前操作的行进行加锁。行级锁能大大减少数据库操作的冲突。其加锁粒度最小,但是加锁的开销也最大。行级锁分为共享锁和排他锁。
特点:开销大 ,枷锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
表级锁:是MySQL中粒度最大的一种锁,表示对当前操作的整张表加锁,他实现简单,资源消耗少,被大部分MySQL引擎支持。最常用的MYISAM与INNODB都支持表级锁定。表级锁分为表共享读锁(共享锁)和表独占写锁(排它锁)。
特点:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
页级锁:页级锁是MySQL中锁定粒度介于行级锁和表级锁中间的一种锁。表级锁速度快但是冲突多,行级锁冲突少但是速度慢。所以取了折中的页级锁,一次锁定相邻的一组记录。BDB支持页级锁。
特点:开销和加锁时间介于表级锁和行级锁中间,会出现死锁;锁定粒度介于表级锁和行级锁之间,并发度一般。
MySQL常用存储引擎的锁机制
MYISAM和MEMORY采用表级锁。
BDB采用页级锁或表级锁,默认为页面锁。
INNODB支持行级锁和表级锁,默认为行级锁。
INNODB的行锁和表锁。
INNODB行锁是通过给索引上的索引项加锁来实现的,这一点MySQL和Oracle不同,后者是通过在数据块中对相应数据行加锁来实现的。INNODB这一特点意味着:只有通过索引条件检索数据,INNODB才使用行级锁,否则,INNODB使用表级锁。