MYSQL数据库锁

前言

数据库为什么需要锁呢?这是为了防止多人操作同一数据时,破会数据一致性的情况。举个例子:(正在吃饭的请吃完饭在读)厕所的坑是有数的,当大家需要排泄的时候便需要去蹲坑(假设厕所是一个小单间,有隔板、有锁),在有坑的时候(也就是资源),大家便会上去占用资源。那么没有呢,便会等待。等待锁打开的时候,你才能进去占用茅坑。

类型

这里锁的类型,博主这里会从多个角度分析,希望大家能够喜欢,有错误的地方请在下方评论指出,博主会及时修正。由于MySQL数据库的锁机制是根据存储引擎不同而不同,这里博主根据不同引擎引入不同类型的锁机制。

MyISAM引擎

MyISAM引擎是MySQL数据库的默认存储引擎,但是在5.7版本后需要在表后声明使用MyISAM引擎,才能使用该引擎(具体是从哪个版本开始,博主不是很清楚,博主使用的是MySQL5.7版本便是这种情况,所以博主便指定这个版本,大家知道的话可以跟博主说一下,谢谢大家)。

表锁

表锁是MyISAM引擎支持的唯一锁机制,那么什么是表锁?表锁有什么用呢?

  • 表锁解释
    表锁机制就是每次锁定一张表的机制。表锁机制粒度最大(粒度可以理解为范围),也是最容易出现锁冲突现象(锁冲突现象:将资源看做一个库房,一个仓库管理员A打开门进入并从里边上锁,外边不可打开。仓库管理员B只能排队等待仓库管理员A用完资源,并在外边上锁,才能进入仓库)。
  • 优缺点
    优点:开销小、不会出现死锁问题。
    缺点:出现锁冲突概率很大。
表级锁类型
  • 表共享读锁
    不会阻塞其他用户对表的读操作,但会阻塞写的请求。
  • 表独占写锁(串行执行)
    阻塞其他用户对表的任何读写请求。
测试
  • 添加只读锁
LOCK table student READ;

添加只读锁
添加只读锁后不允许用户进行写操作(包含insert、updata、delete)。测试如下:

INSERT INTO student VALUES ('35469','gh','Biology',6);

测试写操作
查看写数据进程:

SHOW PROCESSLIST;

写数据进程
消除锁

UNLOCK TABLES;

消除锁
重新插入数据:

INSERT INTO student VALUES ('35469','gh','Biology',6);

插入数据

  • 添加写锁
LOCK TABLE student WRITE;

写锁
添加写锁后,不允许用户进行写和读操作。测试如下:

SELECT * FROM student;

测试
查看读数据进程:

SHOW PROCESSLIST;

读取数据进程
消除锁

UNLOCK TABLES;
FLUSH PRIVILEGES;

消除锁
读取数据

SELECT * FROM student;

读取数据

InnoDB引擎

InnoDB引擎既支持表锁又支持行锁。行锁顾名思义便是给数据记录添加行锁机制(数据记录是指对应于数据源中一行信息的一组完整的相关信息。)。但InnoDB引擎不是对数据记录加锁而是对数据记录的索引项加锁。

行锁

InnoDB引擎是对数据记录的索引项加锁。行锁都是基于索引的,若没有索引则会转换成表锁。

行锁类型
排它锁(写锁)

排它锁又称为写锁((eXclusive lock,简记为X锁)),若事务T对数据对象A加上X锁,则只允许T读取和修改A,其它任何事务都不能再对A加任何类型的锁,直到T释放A上的锁。它防止任何其它事务获取资源上的锁,直到在事务的末尾将资源上的原始锁释放为止。

博主的理解:假设目前只有一本《MySQL数据库概念》书,博主和各位都想去“读写”,如果博主先占用了该资源,并盖上博主的标签(锁)。那么大家就不能再添加任何标签(锁),但可以读取。
InnoDB引擎默认的修改数据语句,update、delete、insert都会自动给涉及到的数据加上排他锁,select语句默认不会加任何锁类型。若加排他锁,则可以使用select …for update语句。
测试数据:

  1. 利用select…for update进行加排它锁查询(这里student.ID为主键也相当于索引)
BEGIN;
SELECT * FROM student WHERE student.ID='00128' FOR UPDATE;
-- COMMIT

排它锁

  1. 测试添加其他排它锁
SELECT * FROM student WHERE student.ID='00128' FOR UPDATE;

测试排它锁

  1. 不添加排它锁查询
SELECT * FROM student WHERE student.ID='00128';

查询

共享锁(读锁)

共享锁(S锁)又称为读锁,若事务T对数据对象A加上S锁,则事务T只能读A;其他事务只能再对A加S锁,而不能加X锁,直到T释放A上的S锁。这就保证了其他事务可以读A,但在T释放A上的S锁之前不能对A做任何修改。

博主理解:所谓共享锁就是博主加了一把S锁,其他用户也可加S锁但不能加X锁。举个例子:假设博主拥有了一个楼盘用于出租,楼盘每层都有卫生间,卫生间有一面镜子,每层卫生间的厕所都是公用的,每个商户都可以去用这面镜子,但不能在这面镜子上乱写乱花画。也就是说,如果事务T对数据A加上共享锁后,则其他事务只能对A再加共享锁,不能加排他锁。获准共享锁的事务只能读数据,不能修改数据。对于select操作,InnoDB不会对数据加任何锁,如果需要,事务可以给select操作显式的加共享锁使用select…lock in share mode。
测试数据:

  1. 利用select … lock in share mode添加共享锁
BEGIN;
SELECT * FROM student WHERE student.ID='00128' lock in share mode;
-- COMMIT;

添加共享锁

  1. 测试其他用户是否可以使用共享锁或者排它锁
select user();

使用gsw用户

SELECT * FROM student WHERE student.ID='00128' lock in share mode;

测试共享锁

SELECT * FROM student WHERE student.ID='00128' for update;

测试排它锁

  1. 去除锁
UNLOCK TABLES;

去除锁

总结

以上是博主初步的一个学习总结,哪里有问题请及时指出,大家一起进步。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lveson

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值