mysql机制魔板_mysql中的锁机制之表锁 - 小周博客,小周个人博客,程序猿小王子,技术博客,个人博客模板,php博客系统,设计模式,wzyl - 黑夜遮不住光亮...

本篇博文的mysql版本:5.7.26

1、概述

表锁比较偏向MYISAM存储引擎,开销小,加锁快,无死锁,锁定粒度大,发生锁冲突的概率最高,并发最底。整张表就只能一个人使用。

2、建表语句和数据-- 创建一张MyISAM存储引擎的数据表

CREATE TABLE `locktest`  (

`id` int(11) NOT NULL AUTO_INCREMENT,

`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

PRIMARY KEY (`id`) USING BTREE

) ENGINE = MyISAM AUTO_INCREMENT = 6 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- 插入测试数据

INSERT INTO `locktest` VALUES (6, '张无忌');

3、查看表是否被锁定show open tables like '%locktest%'

示例截图:

7ac973e235a6393865aebabc5924539e.png

上图中的In_use列是0 表示locktest表没有被加锁

4、对表进行加锁

语法:lock table 表名 read|write

也可以锁定多个表,语法是:lock table 表1 read|wirte,表2 read|wirte

示例:-- 给locktest这张表加上 读锁(也就是 共享锁)

lock table locktest read;

-- 查看locktest这张表的状态,是否被锁定

show open tables like '%locktest%'

示例截图:

81d0827a1e74194d041a6a78e9cc0775.png

上图中的In_use列是1 表示locktest表已经被加锁

5、对表进行解锁

unlock tables

示例:unlock tables

示例截图:

99634a67d5fa1960c77f93ba1f7f2c39.png

上图中可以看到我们进行了解锁操作,然后再次查看locktest表的锁定状态,发现已经是解锁的状态了。

6、读写锁对操作和性能会产生哪些影响?

先来做一下准备工作:

①、继续创建一张表:CREATE TABLE `customer`  (

`id` int(11) NOT NULL,

`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

PRIMARY KEY (`id`) USING BTREE

) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

INSERT INTO `customer` VALUES (1, '敏敏特穆尔');

②、然后使用2个客户端分别连接上mysql,我这里用的是Navicat Premium和mysql命令行版,下面的演示中我会将Navicat Premium称为:会话1。mysql命令行版称为:会话2。

2个mysql客户端示例截图如下:

会话1:

6c89cff0f2d70d2b53afe3b76a7595f5.png

会话2:

92de81b27b2c739726d75e2cb3172556.png

6.1、在会话1中对locktest表添加读锁(读锁也称为:共享锁)lock table locktest read;

c1b62656df34f5927335ed0b63a64235.png

当前连接(也就是 会话1):

是否可以查看自己?

答:可以

示例截图:

6b1ac4f3d8c58eba21eb2145a9a7cd74.png

是否可以更新数据?

答:不可以

示例截图:

f5d702bff34b2295662b61bcc2e6b35c.png

能不能读别的表?

答:不可以!!!自己锁定的当前表还没有进行解锁,不能放下当前还未进行解锁的表,操作别的表!

示例截图:

efadc929d56ae1b53736dae1482d7ee8.png

另一个连接(也就是 会话2):

是否可以查看被 会话1 中锁定的表?

答:可以

示例截图:

9adecf084f58aa73b4c0f9609fa5cf2f.png

能不能读别的表(未被会话1中锁定的表)?

答:可以

示例截图:

9ad877f7c3827e38789701d995b5ad68.png

是否可以更新数据(更新被会话1中锁定的locktest表的数据)?

答:可以。但是,当更新时,会出于阻塞状态,只有等待会话1中进行解锁后,此时才会进行更新操作。

示例截图:

09a125b374deef19e3bd5e4cee3625ec.png

上图中可以看到,当我们进行更新的时候,mysql会一直处于阻塞等待的状态。

我们在会话1中将locktest表进行解锁,然后看会话2中 mysql的反映,会发现当会话1中将locktest表进行解锁之后,会话2中的更新locktest表的操作会立即执行。

示例截图:

70308b1a77e0a80fbe7b941aefeb66bc.png

6.2、在会话1中对locktest表添加写锁(写锁也称为:排它锁)lock table locktest write;

注意:此时我们的locktest表中没有加任何锁了,上面加的读锁,在最后也被释放了。这里加上写锁之后,locktest表中只处于被 写锁的状态,不存在读锁的状态。

示例截图:

8dd0e1e390e28c2f88fc70e4d6aa75a3.png

当前连接(也就是 会话1):

能否读自己锁过的表?

答:可以

示例截图:就不截取了。。

能否修改自己锁过的表?

答:可以

示例截图:就不截取了。。

能否读取别的表?

答:不可以!因为当前自己锁定的表还没有被释放掉,所以不可以读取别的表。

示例截图:就不截取了。。

另一个连接(也就是 会话2):

能否操作在会话1中没有被加过锁(写锁)的表?

答:可以,无论是读取还是更新数据,都不受影响。

示例截图:就不截取了吧。。

能否对被锁过(写锁)的表进行读取或更新操作?

答:不能,会处于阻塞。等待会话1中解锁时, 才能查到或更新。因为会话1中加的锁是写锁(排它锁),即使在会话2中进行查询操作,也不会立即查询到结果。

示例一个查询操作截图:

added6b3ea6fd8c86b1a3e03b3c5d9c7.png

更新操作的截图就不截取了。。

写锁(排它锁)总结:一旦某一张表被加上写锁,那么不管其它连接到mysql的客户端是查询还是更新被加上写锁的那张表,只要加上写锁的那个mysql客户端连接还没有释放锁,那么其它连接到mysql客户端的 想要操作被加上写锁的那张表 只能处于等待阻塞状态。对应的mysql客户端释放锁之后,被阻塞的操作才会进行查询或更新操作。排它锁排它锁 就是排斥作用比较强。

一句话总结:表加写锁后,则只有当前线程对锁定的表,可以执行任何操作。其它线程的操作会被阻塞。

7、表锁的分析及选择

可以使用如下语句分析:

show status like 'table%';

出现的结果中以下2个值比较重要:

①、Table_locks_immediate:产生表级锁定的次数。表示的是能够立即获得表级锁的锁查询次数。网上普遍说的是:释放表锁数(可以立即释放的数量,其实说的都是一个意思,还没有释放,不要理解成已经释放了。)

②、Table_locks_waited:出现表级锁定争用而发生等待的次数

表锁的选择:

MyISAM的读写锁调度是写优先,这也是MyISAM不适合做写为主表的引擎。因为写锁后,其它线程不能做任何操作,大量更新会使用查询很难得到锁,从而造成永久阻塞。

如果读取的操作比较多,那么就可以使用表锁。如果更新的操作比较多 就不要使用表锁。

再见不是离别  而是承诺    -->九夜茴【匆匆那年】

声明:禁止任何非法用途使用,凡因违规使用而引起的任何法律纠纷,本站概不负责。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值