文档章节

-mysql-锁2

凯哥学堂
 凯哥学堂
发布于 2017/09/01 15:47
字数 2890
阅读 8
收藏 0
点赞 0
评论 0

声明:本栏目所使用的素材都是凯哥学堂VIP学员所写,学员有权匿名,对文章有最终解释权;凯哥学堂旨在促进VIP学员互相学习的基础上公开笔记。

表级锁:

之前我们介绍了行级锁,顾名思义行级锁就只是锁住一行或多行数据,因为针对的是行去锁的,因为一个表格内会有很多行数据,要在这些数据中去锁定其中几行数据,是比较耗费资源。而表级锁则是可以锁住整个表,所以相对于行级来说没那么耗费资源,表级锁有两个模式:只读模式和只写模式,这和文件权限里的只读只写有点类似。 在一般情况下表格锁并不经常使用,在这里只是介绍一下如何使用表级锁,和解锁表级锁,而且表级锁的资料都可以在网络上查找到,所以了解一下即可,在mysql官方也有表格锁语法的文档:

https://dev.mysql.com/doc/refman/5.6/en/lock-tables.html

使用只读模式的表级锁,语法:

LOCK TABLES 表名 READ
示例:

image

我们再打开一个客户端来看看能否使用SELECT语句查询这个带有表级锁的表格的数据:

image

因为我们使用的是只读模式的表级锁,自然每个用户都可以读取、查询这个表格的数据,那么我们可以尝试一下update这会对表格数据修改的语句能否执行:

image

在行级锁里即便某些行数据被上锁了也还是能够使用insert语句插入数据的,那么我们试一下在表格锁里是否能行得通:

image

从结果可以得知在表级锁的只读模式下,是不允许任何用户对上锁的表格进行任何的修改的。

自然的delete语句也无法使用:

image

那么如何解锁呢?看看解锁时会发生什么,解锁表级锁的语法很简单:
UNLOCK TABLES
示例:

image

使用只写模式的表级锁,语法:
LOCK TABLES 表名 WRITE
示例:

image

在表级锁的只写模式里,只有上锁用户可以对表格进行写入数据,其他用户是不可以写入数据的,其他用户就连使用SELECT语句查询数据都不可以:

image

上锁用户可以使用insert语句插入数据,其他用户则不允许这个操作:

image

update语句也是一样的:

image

还有delete语句:

image

如果用户给一张表格上了表级锁,那么这个用户在给这个表格解锁之前就只能操作这个表格,数据库里的其他表格均不可以进行任何的操作,如果操作就会报错:

image

只写模式的解锁语法是一样的,都是UNLOCK TABLES:

image

总结一下表级锁,表级锁就是针对表格进行锁定,相对于行级锁没那么耗资源,表级锁有两个模式,只读模式和只写模式,只读模式下上锁用户和其他用户都只能查询数据不能写入数据,只写模式下上锁用户可以进行查询数据和写入数据,其他用户既不能查询数据,也不能写入数据,执行任何SQL语句都会进入等待状态,一直等到表格解锁为止,当表格解锁的时候在等待中的事务会马上被执行。某个用户对某个表格使用了表级锁的话,就只能操作那个表格,数据库里的其他表格均不可进行任何操作。

悲观锁:

悲观锁(Pessimistic Lock)是一种概念、解决某些问题的模式,并不是一种特定的机制,悲观锁,正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度(悲观),因此,在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)。

所以简单来说悲观锁就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。

例如之前我们做的火车票务系统的小案例,就是使用的悲观锁的方式,在我们的代码里都是借助于数据库自带的锁机制完成的,当用户A在购票时用户B就不能够购票,或者购票失败,这就是在整个数据处理过程中,将数据处于锁定状态,具有很明显的排他性(悲观)。 代码:

image

image

悲观锁的优点与不足:

悲观并发控制实际上是“先取锁再访问”的保守策略,为数据处理的安全提供了保证。但是在效率方面,处理加锁的机制会让数据库产生额外的开销,还有增加产生死锁的机会;另外,在只读型事务处理中由于不会产生冲突,也没必要使用锁,这样做只能增加系统负载;还有会降低了并行性,一个事务如果锁定了某行数据,其他事务就必须等待该事务处理完才可以处理那数据。

乐观锁:

乐观锁( Optimistic Locking ) 相对悲观锁而言,乐观锁假设认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让返回用户错误的信息,让用户决定如何去做。 相对于悲观锁,在对数据库进行处理的时候,乐观锁并不会使用数据库提供的锁机制。一般的实现乐观锁的方式就是记录数据版本。

数据版本,为数据增加的一个版本标识。当读取数据时,将版本标识的值一同读出,数据每更新一次,同时对版本标识进行更新。当我们提交更新的时候,判断数据库表对应记录的当前版本信息与第一次取出来的版本标识进行比对,如果数据库表当前版本号与第一次取出来的版本标识值相等,则予以更新,否则认为是过期数据。

所以实际上乐观锁和悲观锁一样也是一种概念、解决某些业务需求的模式,并不是一种特定的机制,乐观锁的主要实现方式是我们开发人员自己通过在数据库中增加一条存储数据版本的列,然后通过代码来判断这些数据的版本,而不是借助数据库自带的锁来完成的一种锁定数据的模式。

例如我们假设一种情况:用户A和用户B同时在ATM机里往一个账户余额2000元的账户取款,两个用户都查询到账户还有2000元,所以用户A要取款1500,用户B要取款1000,然后这两个取款事务会同时提交,如果这个银行的系统逻辑写得不够好的话,就会出现2000-1500-1000=-500的结果,账户余额就会出现负数。
示意图:

image

在这种取款的情况下,如果使用悲观锁来锁住数据的话,由于其排他性,那么另外一个用户就无法查询账户余额,只能处于等待状态,因为在悲观锁里在事务结束之前数据都是处于锁定状态,而且在银行在这种数据量大的地方,使用共享锁这种行级锁也耗费资源。所以就需要用到乐观锁了,乐观锁只有在操作提交的时候才会去锁定数据。在乐观锁中我们可以给数据设定一个版本号,一旦这个数据发生修改,版本号就会发生变化,每一个操作都会先判断版本号是否是最新的版本号,不是的话就不允许操作,在乐观锁的实现过程中我们并不会使用到数据库自带的锁,所以用户们都可以任意的查询或提交操作。
示意图:

image

下面我们做一个简单的取款系统来演示如何实现乐观锁:
先准备一个表格里面填充一行数据:

image

代码示例:

image

运行结果:

image

乐观锁的优点与不足:

乐观并发控制相信事务之间的数据竞争(data race)的概率是比较小的,因此尽可能直接做下去,直到提交的时候才去锁定,所以不会产生任何锁和死锁。但如果直接简单这么做,还是有可能会遇到不可预期的结果,例如两个事务都读取了数据库的某一行,经过修改以后写回数据库,这时就遇到了问题。

脏读简介:

脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。因为这个【学Java,到凯哥学堂kaige123.com】数据是还没有提交的数据,那么另外一个事务读到的这个数据是脏数据(Dirty Data),依据脏数据所做的操作可能是不正确的。

不可重复读:

在一个事务内,多次读同一个数据。在这个事务还没有结束时,另一个事务也访问该同一数据。那么,在第一个事务的两次读数据之间。由于第二个事务的修改,那么第一个事务读到的数据可能不一样,这样就发生了在一个事务内两次读到的数据是不一样的,因此称为不可重复读,即原始读取不可重复。

幻读:

幻读是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,比如这种修改涉及到表中的“全部数据行”。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入“一行新数据”。那么,以后就会发生操作第一个事务的用户发现表中还存在没有修改的数据行,就好象发生了幻觉一样.一般解决幻读的方法是增加范围锁RangeS,锁定检索范围为只读,这样就避免了幻读。

© 著作权归作者所有

共有 人打赏支持
凯哥学堂
粉丝 10
博文 287
码字总数 257252
作品 0
东城
程序员
造火箭基础篇-数据库

数据库事物 数据库事物的四大特性? 1 原子性 2 隔离性 3 持久性 4 一致性 数据库隔离级别? 1 read-uncommitted 2 read-committed 3 repeatable-read 4 serializable MySQL的innodb引擎默认的...

小鱼嘻嘻 ⋅ 2017/12/23 ⋅ 0

悲观锁总结和实践

最近学习了一下数据库的悲观锁和乐观锁,根据自己的理解和网上参考资料总结如下: 悲观锁介绍(百科): 悲观锁,正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系...

真爱2015 ⋅ 2016/01/07 ⋅ 0

mysql悲观锁总结和实践

最近学习了一下数据库的悲观锁和乐观锁,根据自己的理解和网上参考资料总结如下: 悲观锁介绍(百科): 悲观锁,正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系...

Carl_ ⋅ 2015/02/13 ⋅ 0

mysql查询更新时的锁表机制分析

为了给高并发情况下的mysql进行更好的优化,有必要了解一下mysql查询更新时的锁表机制。 一、概述 MySQL有三种锁的级别:页级、表级、行级。 MyISAM和MEMORY存储引擎采用的是表级锁(table-l...

桔子 ⋅ 2013/06/28 ⋅ 3

关于MySQL InnoDB 锁行还是锁表

http://www.cnblogs.com/mingxuan/archive/2011/10/11/2207560.html 关于mysql的锁行还是锁表,这个问题,今天算是有了一点头绪,mysql 中 innodb是锁行的,但是项目中居然出现了死锁,锁表的...

flyking ⋅ 2014/03/06 ⋅ 0

Mysql并发时经典常见的死锁原因及解决方法

Mysql并发时经典常见的死锁原因及解决方法 1. mysql都有什么锁 MySQL有三种锁的级别:页级、表级、行级。 表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最...

rshare ⋅ 2017/12/06 ⋅ 0

MySQL DBA入门到高级笔记:MySQL架构

http://www.wyzc.com/forum/60180.html?tg=3006123630 MySQL逻辑架构 连接管理与安全性: 1、MySQL会为每一个客户端连接分配一个线程,这个连接的查询只会在这个单独的线程执行。服务器会负责...

大王叫我来巡山Zd ⋅ 2016/03/31 ⋅ 0

Hibernate上路_19-事务的丢失更新

事务的并发问题:脏读、不可重复读、幻读。 脏读:一个事务读取另一个事务未提交的数据。 不可重复读:在一个事务中,读取到另一个事务已经提交update数据,造成两次读取不一样。 幻读:在一...

vigiles ⋅ 2013/11/19 ⋅ 0

MySQL并发引起的死锁案例分析

在做项目的过程中,由于写SQL太过随意,一不小心就抛了一个死锁异常,如下: 表结构如下: SQL语句如下: 原因分析MySQL的事务支持与存储引擎有关,MyISAM不支持事务,INNODB支持事务,更新时...

KingSirLee ⋅ 2016/05/25 ⋅ 0

秒杀技术选型

一、控制库存的技术选型有五个选择 (1)mysql乐观锁 (2)mysql悲观锁 (3)redis的原子操作incr (4)redis的watch(redis乐观锁) (5)redis执行lua脚本 二、测试结果(8核16G,300个线程...

钟主华 ⋅ 2016/06/30 ⋅ 15

没有更多内容

加载失败,请刷新页面

加载更多

下一页

JavaScript零基础入门——(十)JavaScript的DOM基础

JavaScript零基础入门——(十)JavaScript的DOM基础 欢迎大家回到我们的JavaScript零基础入门,上一节课,我们了解了JavaScript中的函数,这一节课,我们来了解一下JavaScript的DOM。 第一节...

JandenMa ⋅ 32分钟前 ⋅ 0

Spring mvc DispatchServlet 实现原理

在Spring中, ContextLoaderListener只是辅助类,在web 容器启动的时候查找并创建WebApplicationContext对象,通过该对象进行加载spring的配置文件。而真正的逻辑实现其实是在DispatcherSer...

轨迹_ ⋅ 43分钟前 ⋅ 0

Weex起步

本教程假设你已经在你的本地环境安装了node 其实weex起步教程在 https://github.com/lilugirl/incubator-weex 项目说明文件中都已经有了,但为了有些同学看到英文秒变文盲,所以这里我重新写...

lilugirl ⋅ 51分钟前 ⋅ 0

Jenkins实践1 之安装

1 下载 http://mirrors.jenkins.io/war/latest/jenkins.war 2 启动 java -jar jenkins.war 前提:安装jdk并配置环境变量 启动结果节选: ************************************************......

晨猫 ⋅ 58分钟前 ⋅ 0

组合数学 1-2000 中,能被6或10整除的数的个数

1--2000 中,能被6或10整除的数的个数 利用集合的性质 能被6整除的个数 2000/6 = 333 能被10整除的个数 2000/10 = 200 能被6和10整除的个数 2000/30 = 66 能被6或10整除的个数 333+200-66 =...

阿豪boy ⋅ 今天 ⋅ 0

一篇文章学懂Shell脚本

Shell脚本,就是利用Shell的命令解释的功能,对一个纯文本的文件进行解析,然后执行这些功能,也可以说Shell脚本就是一系列命令的集合。 Shell可以直接使用在win/Unix/Linux上面,并且可以调用...

Jake_xun ⋅ 今天 ⋅ 0

大数据工程师需要精通算法吗,要达到一个什么程度呢?

机器学习是人工智能的一个重要分支,而机器学习下最重要的就是算法,本文讲述归纳了入门级的几个机器学习算法,加大数据学习群:716581014一起加入AI技术大本营。 1、监督学习算法 这个算法由...

董黎明 ⋅ 今天 ⋅ 0

Kylin 对维度表的的要求

1.要具有数据一致性,主键值必须是唯一的;Kylin 会进行检查,如果有两行的主键值相同则会报错。 2.维度表越小越好,因为 Kylin 会将维度表加载到内存中供查询;过大的表不适合作为维度表,默...

无精疯 ⋅ 今天 ⋅ 0

58到家数据库30条军规解读

军规适用场景:并发量大、数据量大的互联网业务 军规:介绍内容 解读:讲解原因,解读比军规更重要 一、基础规范 (1)必须使用InnoDB存储引擎 解读:支持事务、行级锁、并发性能更好、CPU及...

kim_o ⋅ 今天 ⋅ 0

代码注释中顺序更改 文件读写换行

`package ssh; import com.xxx.common.log.LogFactory; import com.xxx.common.log.LoggerUtil; import org.apache.commons.lang3.StringUtils; import java.io.*; public class DirErgodic ......

林伟琨 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部