mysql锁 实战测试代码
存储引擎 | 支持的锁定 |
MyISAM | 表级锁 |
MEMORY | 表级锁 |
InnoDB | 行级锁 |
BDB | 页面锁 |
表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。
锁定方式 | 执行锁定的线程 读 | 其他线程 读 | 执行锁定的线程 写 | 其他线程 写 |
读锁 | 可读 | 可读 | 不可写 | 不可写 |
写锁 | 可读 | 不可读 | 可写 | 不可写 |
涉及工具:Navicat和SQLyog(不能使用phpMyAdmin)
测试代码
测试一:读锁。说明:自己与其他线程只能读取该表
在Navicat中执行以下代码
mysql> lock table `cat` READ;
Query OK, 0 rows affected
mysql> SELECT * FROM `cat` WHERE 1;
+----+--------+
| id | remark |
+----+--------+
| 1 | ceshi |
| 2 | 22222 |
| 3 | 33333 |
+----+--------+
3 rows in set
mysql> UPDATE `cat` SET remark= 'Navicat' WHERE id=1;
1099 - Table 'cat' was locked with a READ lock and can't be updated
在SQLyog中执行
mysql> SELECT * FROM `cat` WHERE 1; +----+--------+ | id | remark | +----+--------+ | 1 | ceshi | | 2 | 22222 | | 3 | 33333 | +----+--------+ 3 rows in set mysql> UPDATE `cat` SET remark= 'SQLyog' WHERE id=1
SQLyog执行UPDATE时,一直都是执行中。当解锁时,执行成功。
在Navicat中执行解锁操作
mysql> unlock tables;
执行后,SQLyog的UPDATE执行成功。
测试结果:
当进行读锁时,锁定线程可进行查询操作,不可进行写入操作。其他线程可进行查询操作,不可进行写入操作。
测试一:写锁。说明:只有当前线程能够对表进行写入操作(其他线程也无法读这部分数据)
在Navicat中执行以下代码
mysql> LOCK TABLE cat WRITE;
Query OK, 0 rows affected
mysql> select * from `cat` where 1;
+----+--------+
| id | remark |
+----+--------+
| 1 | SQLyog |
| 2 | 22222 |
| 3 | 33333 |
+----+--------+
3 rows in set
mysql> update `cat` set remark= 'Navicat' where id=1;
Query OK, 1 row affected
Rows matched: 1 Changed: 1 Warnings: 0
然后在SQLyog中执行
mysql> select * from `cat` where 1;
和
mysql> update `cat` set remark= 'Navicat' where id=1;
可见都是一直是执行状态。只有解锁后,SQLyog才能执行成功
在Navicat中执行解锁操作
mysql> unlock tables;
SQLyog执行成功。
测试结果:
写锁后,执行写锁的线程可进行读和写,其他线程不可进行读和写