一、锁概述
两个事务的写操作之间的互相影响。隔离性要求同一时刻只能有一个事务对数据进行写操作,InnoDB通过锁机制来保证这一点。
锁机制基本原理:
事务在修改数据之前,需要先获得相应的锁;获得锁之后,事务便可以修改数据;该事务操作期间,这部分数据是锁定的,其他事务如果需要修改数据,需要等待当前事务提交或回滚后释放锁。
按照锁粒度分:
1.表锁
表级锁,增删改操作时,会给整张表加锁。myisam支持表级锁,InnoDB支持表级锁,但是默认没有使用。
特点:虽然加锁的开销小,但是并发性能低。
2.间隙锁(Next-Key锁)
增删改操作时,会给满足某些条件,或者满足某个区间的行进行加锁。即使用范围条件,而不是相等条件检索。InnoDB会给符合条件的已有数据记录的索引项加锁;对于键值在条件范围内但并不存在的记录称为间隙,InnoDB也会对这个“间隙”加锁。
3.行锁
Mysql中锁粒度最细的一种锁,表示只针对当前操作进行加锁。即一个事务对某行数据进行操作时,其他事务不能对本行进行操作。行级锁能大大减少数据库操作的冲突,其加锁粒度最小,但是加锁的开销最大。行级锁分为共享锁和排他锁。
特点:
开销大,加锁慢;锁的粒度最小,发生锁冲突的概率最低;并发性能高。
注:表锁、间隙锁和行锁都是排它锁。增删改自带锁。
共享锁和排他锁针对查操作。可以为查询语句添加共享锁和排他锁。
共享锁:
又称读锁,为一个查询语句添加共享锁后,其他事务可以读取,但是不能再添加排他锁。(这里的排他锁指的是增删改操作)。
select … lock in share mode
上面的例子中可以看出,在右侧的事务中为id=5的数据添加共享锁后,左侧事务可以查询到id=5的记录,但是不能修改id=5的数据(排他锁)。
排他锁:
为一个查询语句添加排他锁后,其他事务就不能为加锁的数据添加其他锁了。共享锁也是不可以。update,delete,insert语句都会自动给涉及到的数据加上排他锁,select语句默认不会加任何锁类型。
select …for update