MySQL表锁、行锁的小实验

数据准备

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
CREATE DATABASE `test`;
use test;

CREATE TABLE `user1`(
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR(30) NOT NULL DEFAULT '',
`age` INT NOT NULL DEFAULT 0
)ENGINE=InnoDB DEFAULT CHARSET=UTF8;

-- 测试数据
INSERT INTO user1 (name, age) VALUES
('a', 1),
('b', 2),
('c', 3),
('d', 4),
('e', 5);

开启事务机制,锁定一行

Select Code
1
2
3
4
5
-- 开启事务
begin;

-- 锁定一行
SELECT * FROM user1 WHERE name='a' AND age=1 for update;

说明:for update是锁表的操作。

行锁的特点:InnoDB存储引擎是通过索引上的索引项加锁来实现的,这就意味着:只有通过索引条件检索数据,InnoDB才会使用行级锁。否则,InnoDB将使用表锁。

锁定同一个表中的另外一行数据

Select Code
1
2
3
-- 打开另一个窗口执行上面的步骤
begin;
SELECT * FROM user1 WHERE name='b' AND age=2 for update;

结果:表被锁定,此操作无效。

下一步:给name这个字段添加索引,这样InnoDB将被执行行锁而不是表锁。

操作命令:

Select Code
1
2
-- 添加索引
ALTER TABLE user1 ADD INDEX index_name(name)

查看表索引

结论:
没有索引的情况下,会出现表锁;
InnoDB支持行锁,但是行锁需要有索引的支持,如果没有索引则是表锁
MyISAM只支持表锁,这也是为什么MySQL新版是默认使用InnoDB存储引擎。
InnoDB支持行锁定