一、表锁
创建表最后面增加 engine = myisam,使用 MyISAM 引擎,MySAM 使用的是表锁,适合读,不适合频繁写的表。
1. 相关命令
1. 查询所有表的锁使用情况
show open tables;
database: 数据库
table: 表名
in_use: 是否加了锁
2. 给表加锁
lock table 表名1 read或write[, 表名2 read或write];
3. 给所有表取消使用的锁
unlock tables;
4. 锁分析
show status like 'table%'
table_locks_immediate: 产生表级锁定的次数,能立即获取表的次数,和下面相反
table_locks_waited: 被阻塞,不能立即获取表的次数,此值越高说明争抢越严重
2.读、写锁
1. read
当前线程 | 其他线程 | |
---|---|---|
读加锁的表 | ok | ok |
读未加锁的表 | error | ok |
写加锁的表 | error | 阻塞 |
写未加锁的表 | error | ok |
2. write
当前线程 | 其他线程 | |
---|---|---|
读加锁的表 | ok | 阻塞 |
读未加锁的表 | error | ok |
写加锁的表 | ok | 阻塞 |
写未加锁的表 | error | ok |
二、行锁
用 InnoDB 引擎,行锁不用像表锁中显式声明,开启事务即可
当前事务 | 其他事务 | |
---|---|---|
不同行读 | ok | ok |
同行读 | ok | ok |
不同行写 | ok | ok |
同行写 | 阻塞 | 阻塞 |
对于不同行的读写,两个事务互不干扰,可以各自进行;
若事务读同一行数据,可以读,查询结果遵循隔离级别;
若事务写同一行数据,后写者会阻塞。
所以,InnoDB 引擎下,开启事务就能解决并发写的问题。
*注意:索引失效将导致行锁变表锁
间隙锁(next-key锁)
当一个事务使用用范围检索时,这个范围内的所有索引建值,即使并不存在这个键值;对于被锁定却并不存在的记录,就称为间隙,此时是插入相关的数据会受到阻塞,而这种锁机制就是“间隙锁”。
比如:一个事务中使用了 where id > 10 这个条件,那么,即使没有 id = 11 的数据,里一个事务也无法插入 id 为 11 的数据。
如何锁定指定行?
查出改行数据并在结尾增加 for update,例如:
select * from t1 where id=1 for update;
这样即可锁定 id=1 的这行数据。
相关命令
#锁信息
show status like 'innodb_row_lock%'
网友评论