MySql-锁
程序员文章站
2024-03-24 08:24:10
...
数据库锁
- 表锁
- 行锁
- 间隙锁
锁是计算机协调多个进程或线程并发访问某一资源的机制
表锁
偏向myisam存储引擎,开销小,加锁快,锁定粒度大,发送锁冲突的概率最高,并发度低。
-- 创建表
create table lock_text(
id int not null primary key auto_increment,
name varchar(20)
)engine myisam;
--插入数据
insert into lock_text(name) values('a'),('b'),('c'),('d'),('e');
-- 手动加锁
lock table lock_text read;
-- 释放锁
unlock tables;
MyISAM会自动执行表的加锁,解锁操作,一般不需要手动加锁
- 对MyISAM表的读操作(读锁),不会阻塞其他进程对同一表的读取请求,但会阻塞同一表的写请求,只有当锁释放后,才能执行其他写操作
- 对MyISAM表的写操作(写锁),会阻塞其他进程对同一表的读写操作,直到锁释放,才能执行其他读写操作
行锁
innodb引擎有行锁和表锁,行锁开销大,加锁慢,会出现死锁。锁定力度小,发生锁冲突的概率最低,并发度也高。
-- 创建锁测试表
create table lock_text(
a tinyint(3),
b varchar(3)
)engine=innodb charset=utf8;
-- 插入数据
insert into lock_text values(1,'b2'),
(3,'san'),(4,'两个二'),(5,'嘤嘤嘤');
-- 建索引
create index idx_name on lock_text(name);
-- 分析行锁
show status like 'innodb_row_lock%';
mysql> show status like 'innodb_row_lock%';
+-------------------------------+-------+
| Variable_name | Value |
+-------------------------------+-------+
| Innodb_row_lock_current_waits | 0 |
| Innodb_row_lock_time | 34481 |
| Innodb_row_lock_time_avg | 17240 |
| Innodb_row_lock_time_max | 27045 |
| Innodb_row_lock_waits | 2 |
+-------------------------------+-------+
5 rows in set (0.00 sec)
锁定一行
select * from lock_text where a=1 for update;
variable_name | translate |
---|---|
Innodb_row_lock_current_waits | 当前正在等待锁定的数量 |
*Innodb_row_lock_time | 从系统启动到现在锁定的总时间长度 |
*Innodb_row_lock_time_avg | 每次等待所花费平均时间 |
Innodb_row_lock_time_max | 从系统启动到现在等待最长的一次花费的时间 |
*Innodb_row_lock_waits | 系统启动后到现在总共等待的次数 |
间隙锁
当我们用范围条件而不是常量条件索引数据,并请求共享锁(读锁)或排它锁时(写锁),innodb会给复活条件的已有数据记录的索引项加锁,对于键值在条件范围内但不存在的记录,叫’间隙’,innodb会对这个间隙加锁,这种锁称为间隙锁。
间隙锁的危害
因为sql执行过程中使用范围查找时,它会锁定整个范围内所有的索引值,即使这个键值并不存在,这是一个致命弱点,在锁定范围内无法插入任何数据。
上一篇: 实战java虚拟机06- 锁与并发