Mysql并发控制-锁
共享锁
共享锁也称为读锁,读锁允许多个连接可以同一时刻并发的读取同一资源,互不干扰。
排他锁
排他锁也称为写锁,一个写锁会阻塞其他的写锁或读锁,保证同一时刻只有一个连接可以写入数据,同时防止其他用户对这个数据的读写。
锁策略
table lock(表锁)
- 表锁是mysql最基本的锁策略,也是开销最小的锁,加锁快,会锁定整个表。
- 通常发生在DDL语句和不走索引的DML语句。
update table set columnA = "a" where columnB = "b";
如果上述sql语句中columnB字段不存在索引或者不是组合索引前缀,会进行锁表操作。
如果columnB字段创建索引后,那么会锁住满足where条件的行(行锁)。
row lock (行锁)
行锁可以最大限度的支持并发处理,当然也带来了最大开销,加锁慢,行锁的粒度在每一行数据。
- InnoDB行锁是通过给索引上的索引项加锁来实现的:只有通过索引条件检索数据,InnoDB才使用行级锁,否则将使用表锁。
- 不论是主键索引、唯一索引或者普通索引,InnoDB都会使用行锁来对数据加锁。
- 只有执行计划真正使用了索引,才能使用行锁,可以通过explain来检查SQL的执行计划。
- 如果多个session访问不同行的记录,使用了相同的索引键,是会出现索引冲突的。
InnoDB 间隙锁
当我们用范围条件而不是相等检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录的索引项加锁;对于键值在条件范围内但是并不存在的记录,叫做“间隙(GAP)”,InnoDB也会对这个间隙加锁,这种锁机制就是间隙锁(Next-Key锁)。
很显然,在使用范围条件检索并锁定记录时,InnoDB这种加锁机制会阻塞符合条件范围内键值得并发插入,造成严重的锁等等。所以应尽量使用相等条件访问更新数据。
间隙锁的目的:
- 防止幻读,以满足相关隔离级别的要求;
- 满足恢复和复制的需要。
显式锁 与 隐式锁
隐式锁:我们上文说的锁都属于不需要额外语句加锁的隐式锁。
显示锁:
SELECT ... LOCK IN SHARE MODE(加共享锁);
SELECT ... FOR UPDATE(加排他锁);
网友评论