MySQL中的锁机制

这篇具有很好参考价值的文章主要介绍了MySQL中的锁机制。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

抛砖引玉:多个查询需要在同一时刻进行数据的修改,就会产生并发控制的问题。我们需要如何避免写个问题从而保证我们的数据库数据不会被破坏。

锁的概念

读锁是共享的互相不阻塞的。多个事务在听一时刻可以同时读取同一资源,而相互不干扰。

写锁的排他的。一个写锁会阻塞其他写锁或读锁。出于安全考虑只有这样才能保证在给定的时间里只有一个事务能够执行写入,并防止其他事务读取正写入的同一资源。

锁带来的问题

通过锁定机制可以实现事务的隔离性要求,使得事务可以并发的工作,同时也带来了三个问题:脏读,不可重复读和丢失更新。

脏读

脏数据:未提交的数据

如果读到了脏数据即一个事务可以读取到另一个事务中未提交的数据那就违背了事务的隔离性。

所以脏读是指在不同的事务下,当前事务可以读取到另外事务的未提交的数据,简单来说就是可以读取到脏数据。

演示:

初始状态:

将会话A,B设置隔离级别为RU

set session transaction isolation level READ UNCOMMITTED;

会话A插入一条数据

这时候事务B在此执行查询操作,会发现事务B读取到了事务A新增的数据。注意:此时事务A没有提交。

不可重复读

在一个事务中两次读取到的数据是不一样的,这中情况被称为不可重复读。

与脏读的区别:脏读是读取到了未提交的数据,而不可重复读是读取到的却是已经提交的数据,但是违反了数据库事务一致性的要求。

演示:

事务B插入一条数据并且提交

事务A在此执行select语句,事务A读取到了事务B提交的数据

一般来说不可重复读问题是可以接受的,因为读取到的是已经提交的数据,本身不会带来什么问题。例如Oracle 和 SQL Server的默认的事务隔离级别就是RC。 MySQL默认的事务隔离级别是RR。

在MySQL InnoDB中通过使用 Next-key lock 算法来避免不可重复读问题,并且将不可重复读问题定义为幻读(Phantom problem)

丢失更新

一个数据的更新会被另一个事务的更新操作所覆盖,从而导致数据的不一致性。

第一种丢失:

A事务撤销时,把已经提交的B事务的更新数据覆盖了。这种错误可能造成很严重的问题,通过下面的账户取款转账就可以看出来:

时间 取款事务A 转账事务B
T1 开始事务
T2 开始事务
T3 查询账户余额为1000元
T4 查询账户余额为1000元
T5 汇入100元把余额改为1100元
T6 提交事务
T7 取出100元把余额改为900元
T8 撤销事务
T9 余额恢复为1000 元(丢失更新)

第二类丢失更新

A事务覆盖B事务已经提交的数据,造成B事务所做操作丢失:

时间 转账事务A 取款事务B
T1 开始事务
T2 开始事务
T3 查询账户余额为1000元
T4 查询账户余额为1000元
T5 取出100元把余额改为900元
T6 提交事务
T7 汇入100元
T8 提交事务
T9 把余额改为1100 元(丢失更新)

要避免丢失更新的发生,需要让事务在这种情况的操作变成串行化,而不是并行操作。即上面的select操作中加上排他锁。

MySQL锁的分类:

按照锁的粒度来说

MySQL主要包含三种类型(级别)的锁定机制:

全局锁:锁的是整个database。

表级锁:锁的是某个table。 (表排他锁,表共享锁,元数据锁,自增锁)

行级锁:锁的是某行数据,也可能锁定行之间的间隙。由某些存储引擎实现,比如InnoDB。

InnoDB的行级锁,按照锁定范围来说

分为四种:

1.记录锁(Record Locks):锁定索引中一条记录。

2.间隙锁(Gap Locks):要么锁住索引记录中间的值,要么锁住第一个索引记录前面的值或者最后一个索

引记录后面的值。

3.临键锁(Next-Key Locks):是索引记录上的记录锁和在索引记录之前的间隙锁的组合(间隙锁+记录

锁)。

4.插入意向锁(Insert Intention Locks):做insert操作时添加的对记录id的锁。

InnoDB的行级锁,按照功能来说

分为两种:

1.共享锁(S):允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。

2.排他锁(X):允许获得排他锁的事务更新数据,阻止其他事务取得相同数据集的共享读锁和排他写锁。

InnoDB行锁是通过给索引上的索引项加锁来实现的,因此InnoDB这种行锁实现特点意味着:只有通过

索引条件检索的数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁!

注意:插入意向锁

(1)插入意向锁是一种Gap锁,不是意向锁,在insert操作时产生。

(2)在多事务同时写入不同数据至同一索引间隙的时候,并不需要等待其他事务完成,不会发生锁等 待。

(3)假设有一个记录索引包含键值4和7,不同的事务分别插入5和6,每个事务都会产生一个加在4-7之 间的插入意向锁,获取在插入行上的排它锁,但是不会被互相锁住,因为数据行并不冲突。

(4)插入意向锁不会阻止任何锁,对于插入的记录会持有一个记录锁。文章来源地址https://www.toymoban.com/news/detail-645987.html

到了这里,关于MySQL中的锁机制的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • MySQL中的锁(表锁、行锁)

    锁是计算机协调多个进程或纯线程并发访问某一资源的机制。在数据库中,除传统的计算资源(CPU、RAM、I/O)的争用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所在有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性

    2024年02月09日
    浏览(11)
  • Mysql中的锁(理论篇)

    Mysql中的锁(理论篇)

    为什么在可重复读级别下,幻读没有产生? 回想一下在事务隔离级别那篇文章中,可串行化是通过什么保证的? 对操作的每一行记录加读锁、写锁和范围锁;任何其他事务都必须等待持有锁的事务释放锁之后才能进行操作; 而可重复读级别相比之下唯一少的就是范围锁,所

    2024年02月11日
    浏览(14)
  • Mysql中的锁(case篇)

    Mysql中的锁(case篇)

    上篇文档中提到过 WRITE locks normally have higher priority than READ locks to ensure that updates are processed as soon as possible. This means that if one session obtains a READ lock and then another session requests a WRITE lock, subsequent READ lock requests wait until the session that requested the WRITE lock has obtained the lock and released it

    2024年02月11日
    浏览(10)
  • MYSQL中的锁(面试难点重点)

    MYSQL中的锁(面试难点重点)

    首先说一下 这个加锁是个啥子过程呢 我们拿一条记录举例,这个记录就放在这,没人操作它,他就没生成锁结构, 直到有个事务操作它了,然后给它才生成了个锁结构,锁结构两个参数 trx(生成该锁的事务) is_waiting(正在等待就是:true 没在等待就是 false) (锁里面很多参数 这里这

    2024年02月16日
    浏览(17)
  • 详解数据库的锁机制及原理

    详解数据库的锁机制及原理

    本图源自CSDN博主:Stephen.W 数据库锁一般可以分为两类, 一个是悲观锁,一个是乐观锁 乐观锁一般是指用户自己实现的一种锁机制,假设认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让返回用

    2024年02月05日
    浏览(11)
  • epoll准备就绪列表保护机制,引发的锁问题讨论

    epoll 就绪队列应该使用什么数据结构?为什么? 在 Nginx 中,就绪队列通常使用链表来实现。具体来说,就绪队列是一个双向链表,其中每个节点都包含了一个 ngx_event_t 结构体,用于表示一个已经准备就绪的事件。当 epoll 检测到某个文件描述符上有 I/O 事件发生时,就会将相应

    2023年04月13日
    浏览(12)
  • InnoDB锁初探(一):锁分类和RR不同场景下的锁机制

    InnoDB锁初探(一):锁分类和RR不同场景下的锁机制

    数据库锁是Mysql实现数据一致性的基础之一,是在事务的基础之上,基于Mysql Server层或存储引擎层实现的。 前置条件: 查看语句: 按照锁的粒度,可以分为表锁和行锁 共享锁 排他锁 意向锁是表级的 同样具有意向共享锁(IS)、意向排他锁(IX) TABLE LOCK table *** trx id *** lo

    2024年02月09日
    浏览(7)
  • Go 语言中的锁

    并发是同时发生多个计算或事件的能力。并发通常通过同时执行多个任务或进程来实现,这些任务或进程共享相同的资源(例如内存或处理器)。并发使用的基本机制被称为锁。在Go语言中,锁是一个类型变量,它包含一个内部计数器,用于跟踪已获取的锁的数量。当一个g

    2024年01月16日
    浏览(7)
  • 数据库中的锁

    提及事务之间的相互影响时,介绍了脏读、幻读等几种类型的数据错误,为更好避免发生这些错误,引入了对资源的锁定。锁定的存在使得一个事务对他自己的数据块进行操作时,另外一个事务不能插足这个数据块。 锁的分类 从数据库系统的角度,锁模式可分为以下6 种类型

    2024年02月13日
    浏览(9)
  • 编程(39)----------多线程中的锁

    编程(39)----------多线程中的锁

    假设一个这样的场景: 在多线程的代码中, 需要在不同的线程中对同一个变量进行操作. 那此时就会出现问题: 多线程是并发进行的, 也就是说代码运行的时候, 俩个线程会同时对一个变量进行操作, 这样就会涉及到多线程的安全问题: 在这个代码中, 两个线程会分别对count进行自

    2024年02月07日
    浏览(6)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包