博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java共享锁和排他锁的区别_漫话:如何给女朋友解释什么是共享锁和排他锁
阅读量:5741 次
发布时间:2019-06-18

本文共 1896 字,大约阅读时间需要 6 分钟。

dfd6e79c8419a14ea581492b264b7b47.png

周末,我正在看电视剧,是那个小说改编的《斗破苍穹》,看的正嗨的时候,女朋友气哄哄的走过来。

我不喜欢萧炎,太花心,有那么多老婆。

63dd2ff02c17519a66e5f62b0834c45f.png

哈哈,喜欢萧炎的妹子给他加的是共享锁,而不是排他锁。

8d138e4124fff6390f2a6446291dc7e2.png

我看她们共享的是挺开心的,心真大。

74a59c73ecb67f49b772977aeb0dee38.png

这个共享不是你说的意思啦。

8d138e4124fff6390f2a6446291dc7e2.png

共享锁,又称为读锁,获得共享锁之后,可以查看但无法修改和删除数据。

排他锁,又称为写锁、独占锁。获准排他锁后,既能读数据,又能修改数据。

你又跟我拽概念了。我完全听不懂啊。

ac6d4bfc507cca46898f5cc985aec20b.png

你别急,我给你介绍一下你就知道啦。

8d138e4124fff6390f2a6446291dc7e2.png

为什么要加锁

很多人都知道,锁,是用来解决并发问题的,那么什么是并发问题呢?并发情况下,不加锁会有什么问题呢?

拿日常生活中的洗手间举例子,每个洗手间都会有一个门,并且是可以上锁的,当我们进入洗手间之后会把门反锁,当我们出来之后再把锁打开。

当门被锁上的时候,其他人只能在门外等待。洗手间之所以要有门锁,就是为了保护隐私的,避免出现多个人同时进入洗手间的情况。

这和数据库中的锁其实是一样的,为了避免多个事务同时操作数据库导致数据异常,一般会通过锁机制解决。

奥,我懂了,加锁是为了避免并发导致数据出现异常

8d138e4124fff6390f2a6446291dc7e2.png

嗯嗯,是的。

8d138e4124fff6390f2a6446291dc7e2.png

那共享锁和排他锁呢?有啥区别

6c9c423265b29a5041709f1a9d2f432e.png

别急,慢慢来。

8d138e4124fff6390f2a6446291dc7e2.png

在介绍共享锁和排他锁之前,我们先来打个比喻。前面已经用了一个洗手间的例子,那么就继续这个例子,我们拓展一下。

一般情况下,我们进入洗手间有可能做以下几件事儿:洗手、化妆、上厕所等。其实只有上厕所这件事儿是极度隐私的,而其他几件事儿并没有那么隐私。

我们可以认为洗手间就是一个数据库表,而洗手间内部的设施就是数据库表中的数据。

我们每个想要进入洗手间的人都是一个事务。

简单的洗手、化妆等操作可以认为是读操作。而上厕所操作我们认为他是写操作。

共享锁

前面简单介绍了数据库与洗手间之间的类比关系,那么接下来继续分析什么是共享锁。

有些时候,如果我们进入洗手间只是想洗手的话,我们一般不会锁门。而其他人也可以进来洗手、化妆等。但是,其他人是不可以进来上厕所的。

这就是共享锁,也叫读锁。就是我们对数据进行读取操作的时候,其实是不会改变数据的值的。

所以我们可以给数据库增加读锁,获得读锁的事务就可以读取数据了。当数据库已经被别人增加了读锁的时候,其他新来的事务也可以读数据,但是不能写。

也就是说,如果事务T对数据A加上共享锁后,则其他事务只能对A再加共享锁,不能加排他锁。获准共享锁的事务只能读数据,不能修改数据。

用法

在查询语句后面增加LOCK IN SHARE MODE,Mysql会对查询结果中的每行都加共享锁。

SELECT ... LOCK IN SHARE MODE;

当没有其他线程对查询结果集中的任何一行使用排他锁时,可以成功申请共享锁,否则会被阻塞。其他线程也可以读取使用了共享锁的表,而且这些线程读取的是同一个版本的数据。

我明白了什么是共享锁了。那排他锁呢?

6c9c423265b29a5041709f1a9d2f432e.png

听我慢慢道来。

8d138e4124fff6390f2a6446291dc7e2.png

排他锁

介绍完了共享锁后,在来说说互斥锁。

如果我们进入洗手间只是想洗手,那么我们可以允许其他人也进来洗手。但是,如果我们进入洗手间是为了上厕所,那么任何人不能再进来做任何事。

这就是排他锁,也叫写锁。就是我们对数据进行写操作的时候,要先获得写锁,获得写锁的事务既可以写数据也可以读数据。当时,如果数据库已经被别人增加了排他写锁,那么后面的事务是无法在获得该数据库的任何锁的。

也就是说,如果事务T对数据A加上排他锁后,则其他事务不能再对A加任任何类型的封锁。获准排他锁的事务既能读数据,又能修改数据。

用法

在查询语句后面增加FOR UPDATE,Mysql会对查询结果中的每行都加排他锁

SELECT ... FOR UPDATE;

当没有其他线程对查询结果集中的任何一行使用排他锁时,可以成功申请排他锁,否则会被阻塞。

你这个获得排他锁的例子为什么是个读操作呢?

6c9c423265b29a5041709f1a9d2f432e.png

因为写操作会被默认增加排他锁,不需要显示声明啊。

8d138e4124fff6390f2a6446291dc7e2.png

哇,原来数据库这么智能。

4b50f2424ae3d298959e73c8acbd74e0.png

当然了,这样才能更好的保证数据安全呀。

8d138e4124fff6390f2a6446291dc7e2.png

加锁原则

拿MySql的InnoDB引擎来说,对于insert、update、delete等操作。会自动给涉及的数据加排他锁;

对于一般的select语句,InnoDB不会加任何锁,事务可以通过以下语句给显示加共享锁或排他锁。

共享锁:SELECT ... LOCK IN SHARE MODE;

排他锁:SELECT ... FOR UPDATE;

就这样,我给他讲完了乐观锁和排他锁,然后想着终于可以继续去看电视剧了。

你已经被我加上排他锁了,你别想美事儿了了。

4b50f2424ae3d298959e73c8acbd74e0.png

额(⊙o⊙)…

adf3f9a3e9c3a4928e71f0cf3d811f18.png

转载地址:http://bbnzx.baihongyu.com/

你可能感兴趣的文章
P1772 [ZJOI2006]物流运输
查看>>
sizeof && strlen()
查看>>
如何安装Pycharm官方统计代码行插件
查看>>
Release和Debug的区别[转]
查看>>
Unity C#常用API和相关关键字
查看>>
oracle11g 数据库导出报“ EXP-00003:
查看>>
机器学习 —— 基础整理(三)生成式模型的非参数方法: Parzen窗估计、k近邻估计;k近邻分类器...
查看>>
Luogu_2876_[USACO07JAN]解决问题Problem Solving
查看>>
Oracle RAC 并发与架构
查看>>
java空指针异常:java.lang.NullPointException
查看>>
Maven启用代理访问
查看>>
json 序列化的两种方式
查看>>
ABI/EABI/OABI
查看>>
SQL SERVER 2008 利用发布订阅方式实现数据库同步
查看>>
继承和多态 笔记
查看>>
Two Graphs 牛客网暑期ACM多校训练营(第一场)D 图论基础知识 全排列
查看>>
其他进制的数字
查看>>
[LeetCode系列]翻转链表问题II
查看>>
12XML(可扩展标记语言)
查看>>
软件测试职业规划
查看>>