MySQL 锁机制

2020-06-17  本文已影响0人  洛美萨斯

1.MySQL锁机制概述

1.1什么是锁

锁是计算机协调多个进程或纯线程并发访问某一资源的机制。在数据库中,除传统的计算资源(CPU、RAM、I/O)的争用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所在有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素。从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂。

防止更新丢失,并不能单靠数据库事务控制器来解决,需要应用程序对要更新的数据加必要的锁来解决。

1.2锁的运作

事务T在度某个数据对象(如表、记录等)操作之前,先向系统发出请求,对其加锁,加锁后事务T就对数据库对象有一定的控制,在事务T释放它的锁之前,其他事务不能更新此数据对象。

1.3锁定机制分类

锁定机制就是数据库为了保证数据的一致性而使各种共享资源在被并发访问访问变得有序所设计的一种规则。MySQL数据库由于其自身架构的特点,存在多种数据存储引擎,每种存储引擎所针对的应用场景特点都不太一样,为了满足各自特定应用场景的需求,每种存储引擎的锁定机制都是为各自所面对的特定场景而优化设计,所以各存储引擎的锁定机制也有较大区别。
按照锁类型分类:

排它锁:

Session1 Session2
获得表mylock的write锁定 image-20200514041706638 待Session1开启写锁后,Session2再开启终端
当前Session1对锁定表的查询+更新+插入均可执行 image-20200514042202682 其他Session队锁定表的查询被阻塞,需要等待锁被释放 image-20200514042129157
释放锁 image-20200514042245435 Session2获得锁, image-20200514042309422

共享锁:

Session1 Session2
获得mylock的read锁定 image-20200514163038565 连接终端
当前终端可以查看表记录 image-20200514163225001 其他session也可以查询表记录 image-20200514163306373
当前session不能查询其他没有锁定的表 image-20200514163400464 其他session可以更新或查询其他未锁定的表 image-20200514163559463
当前session插入或更新锁定的表会提示错误 image-20200514163902187 其他session插入会更新锁定的表会一直等待 image-20200514163944917
当前session释放锁 image-20200514164102266 session2获得锁,更新操作完成 image-20200514164048105

按照锁的数据粒度分类:

从这里我们应该引申去思考行锁更多的缺点:(因为我们执行sql主要依赖行锁来提高并发度)
1- 比表级锁、页级锁消耗更多内存
2- 如果你在大部分数据上经常进行GROUP BY操作或者必须经常扫描整个表,比其它锁定明显慢很多。
3- 更容易发生死锁。

1.4数据库事务机制

1.4.1事务ACID

事务简称ACID,是恢复和并发控制的基本单位

1.4.2 并发调度问题
不可重复读与幻读的区别:
不可重复读重在修改,就是你刚读过的一个数据,再读一次又一不一样了。
而幻读重在记录的增删,就是你第一次读的数据量,第二次读又不一样了。
所以要解决:
解决不可重复读:这个数据只有在修改事务完全提交后才可读取数据。
解决幻读:符合这个条件下的数据,在操作事务完成处理之前,其他事务不可添加新数据、或者删除数据。

1.5事务隔离级别

这个是mysql用意向锁来解决事务并发问题,为了区别封锁协议,弄了一个新概念隔离性级别:包括Read Uncommitted、Read Committed、Repeatable Read、Serializable。mysql 一般默认Repeatable Read。

1.6活锁与死锁

采用封锁的方法可以有效防止数据的不一致性,单封锁本身会引起麻烦,就是死锁和活锁。

1.6.1活锁

如果事务T1封锁了数据对象R后,事务T2也请求封锁R,于是T2等待,接着T3也请求封锁R。当T1释放了加载R上的锁后,系统首先批准T3的请求,T2只能继续等待。接着T4也请求封锁R,T3释放R上的锁后,系统又批转了T4的请求。这样的一直循环下去,事务T2就只能永远等待了,这样情况叫活锁。

解决办法:采用先来先服务的队列策略。队列式申请。

1.6.2死锁

当两个事务分别锁定了两个单独的对象,这时每一个事务都要求在另一个事务锁定的对象上获得一个锁,因此每一个事务都必须等待另一个事务释放占有的锁。这就发生了死锁了

上一篇 下一篇

猜你喜欢

热点阅读