iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >MySQL数据库锁的实现
  • 335
分享到

MySQL数据库锁的实现

MySQL数据库锁MySQL 2023-03-20 11:03:03 335人浏览 安东尼
摘要

目录1.什么是锁2.锁解决的问题3.并发访问相同记录的几种情况4.理解读锁和写锁4.1 读锁4.2 写锁5.表锁5.1 表级的读/写锁5.2 意向锁6.行锁6.1 记录锁6.2 间隙

数据库事务-锁机制

1.什么是锁

锁,其实就是一个内存种的结构,在事务还没有来之前是没有锁存在的。在事务未开始前只有一条记录,是没有锁和记录之间的关联关系的。

锁结构种有很多的信息,主要的有两个:

  • trx信息:代表这个锁结构是哪个事务生成的。
  • is_waiting:代表当前事务是否在等待。

当一条事务想要对某条记录进行改动时,就会生成一把锁,在生成锁的时候,会去检查该条记录有没有被其他的锁关联。① 如果没有,is_wating就是false,不需要等待,此时表示事务上锁成功,可以进行后续操作;② 如果有其他事务上锁,则is_wating就是true,加锁失败,需要等待其他事务释放锁,才能后续操作该记录。

2.锁解决的问题

数据库锁主要解决并发情况下,数据隔离问题。数据库是可以有多个客户端连接并访问的,这种情况就会有并发操作同一数据记录的情况。因此数据库出现了锁机制,解决各种并发情况下出现的隔离问题。

3.并发访问相同记录的几种情况

  • 读-读:多个事务同事对数据库的同一条记录进行读操作,这种情况对数据库的记录没有发生变化,不会出现什么问题,这种情况不需要解决什么问题。
  • 写-写:多个事务同事对数据库的同一条记录进行写操作,这种情况会发生脏写问题,不管那种隔离级别,都不允许这种情况的发生。所有有多个未提交的事务去操作同一条记录时,需要让其他事务处于阻塞排队等待。
  • 读-写/写-读:在多并发操作同个数据记录时,有的事务在读,有的事务在进行写操作,这种情况会出现脏读、不可重复读、幻读等情况。Mysql在repeatable read隔离级别上,已经解决了幻读的问题。

4.理解读锁和写锁

对于mysql的innoDB存储引擎来说,读锁/写锁可以作用在表上,也可以作用在行上

4.1 读锁

读锁(S)也称共享锁,在多个事务共同读同一个记录时,是可以同时读取,互不影响,互不干扰的。
在进行SELECT查询操作的时候,可以使用读锁,使多个任务之间可以共同读取同一条记录。但在查询操作时,也可以使用写锁,后面讲写锁的时候再说。
如何在读取的时候加锁:

SELECT * FROM student LOCK IN SHARE MODE;
#或者
SELECT * FROM student FOR SHARE;#(mysql 8.0新写法)

4.2 写锁

写锁(X)也称排他锁,在事务在进行写操作时,会上X锁,导致当前事务未完成写操作时,其他事务的读/写会被阻塞。保证在同一个时间内,只有一个事务能对事务进行读/写操作。

  • 在进行读操作的时候,也可以给记录加X锁,防止在读取记录的时候,其他事务对当前记录进行更新。
  • 查询语句加上X锁有,其他事务不能再给该记录加S锁或X锁。其他事务会阻塞,知道当前事务释放X锁。
  • 给查询操作加X锁:
SELECT * FROM student FOR UPDATE;

进行写操作时,会自动给该条记录加X锁。写记录:INSERT\DELETE\UPDATE 4.3 读锁和写锁的兼容情况

读写

5.表锁

表锁是指给所操作的整张表进行加锁,相对行锁,对表加锁的颗粒度比较大,因此它的开销也比较小。由于是对整张数据表进行加锁,因此可以避免死锁的出现。即使这样,是对整张表进行加锁,就会导致大量的事务无法继续操作表,所有表锁的性能是较差的。
在MySQL中,InnoDB提供了表锁行锁由于表锁的性能比较差,一般我们都很少用到表锁。只有特殊场景下会用到表锁,比如:数据崩溃恢复。

5.1 表级的读/写锁

  • 对表加S锁:MySQL的InnoDB对整个表加S锁。
  • 对表加X锁:MySQL的InnoDB对整个表加X锁。

查看有那些表被加锁:

SHOW OPEN TABLES;
#或者
SHOW OPEN TABLES WHERE In_use >0;

手动给表加锁:

LOCK TABLES student READ;#给student表加S锁
LOCK TABLES stdent WRITE;#给student表加X锁

释放锁:

UNLOCK TABLES;

小结

5.2 意向锁

MySQL的InnoDB存储引擎中,支持表锁和行锁同时存在,而意向锁就是表锁的一种。

意向锁是为了协调表锁行锁同时共存而存在的。意向锁是一中不于行锁冲突的表级锁。意向锁用户是无法手动添加的,它是InnoDB存储引擎自动给加的。当在给某个行添加S锁或X锁时,需要先获取当前行所在表的意向锁。

意向锁分为两种:

  • 意向共享锁(IS):事务有意向对表中的某行加共享锁(S锁)。当给某一行记录加了共享锁(S)后,数据库就会给当前的数据表或数据页加上意向共享锁,当想给当前表加入一个排他锁(X)时,就会检测到意向共享锁,就会被排斥阻塞,不能加锁。但是加表的共享锁时,是可以的。
  • 意向排他锁(IX):事务有意向对表中的某行加排他锁(X锁)。当给某一行记录加了排他锁(X)后,数据库就会给当前的数据表或数据页加上意向排他锁,当想给当前表加入一个排他锁(X)或者意向锁(S)时,就会检测到意向排他锁,就会被排斥阻塞,不能加锁。

理解意向锁的意义:当没有意向锁的时候,当事务想要给表加表锁的时候,需要去检测每行记录是否加有锁,这样每条检测的效率非常的低。意向锁的出现,很好的解决这种情况。有意向锁后,事务要表添加锁,只要检查当前表是否有意向锁就可以了。

总结:意向锁之间是互相兼容的和读写锁不兼容:

6.行锁

行锁就是给表中的某条记录上把锁,将该条记录锁住。行锁是在InnoDB存储引擎层实现的,这是InnoDB与MyISAM最大的区别之一。行锁是粒度小的,发生锁冲突的概率很小,因此会实现高并发的效果,但是因粒度较小,加锁较慢,会出现死锁的情况

6.1 记录锁

记录锁就是一把行锁,顾名思义,给某条记录上锁。

  • 共享记录锁(S):当一个事务得到了某个事务的共享锁后,其他事务还能继续获取该记录的共享锁,但是不能获取该记录的排他锁。
  • 排他记录锁(X):当一个事务得到了某个事务的排他锁后,其他事务不能获取该记录的共享锁和排他锁。

6.2 间隙锁

间隙锁是在某个记录前的间隙加入一个锁,这样就使该记录前面的间隙是不能添加数据的。这种间隙锁有效的防止了幻读的出现。间隙锁的出现,也是为了解决幻读而提出来的。
不管是共享锁还是排他锁,起到的作用是一样的,
举例:

select * from student where id=11 for update;

此时id为18加了间隙锁

这种会出现一个问题,因为间隙锁只会锁住行前面的间隙,那么,如果此时给id为25后面的间隙插入数据,就会有问题,此时,数据库做了两个提供了两个伪记录: Infimum记录,表示该页面中最小的记录。 Supremun记录,表示该页面中最大的记录。
加入如下,就可以阻止其他事务加入(25,+∞)的数据了。

select * from student where id > 20 lock in share mode;

间隙锁的出现,会发生死锁,如下:

当记录中存在间隙锁时,有其他事务想在这个间隙插入数据,由于锁的存在,会阻止插入,让事务进行等待,知道释放间隙锁。此时内存中会生成一个插入意向锁,这个意向锁是一种间隙锁,并不是表锁中的意向锁。这种插入意向锁可以有多个,一个间隙中有多个插入意向锁并不冲突,插入意向锁之间不会有排斥。

6.3 临界锁

临界锁是用来补充上面说的间隙锁,因为间隙锁只是锁住了记录前面的间隙,但是并不包含自己,因此临界锁就出现了,临界锁就是记录锁和间隙锁的组合体。

select * from student where id <=18 and id > 10 for update;

7.悲观锁和乐观锁

悲观锁、乐观锁其实并不是一种锁,而是一中并发下锁的一种设计思想

7.1 悲观锁

  • 悲观锁,就是很悲观,对数据被其他事务操作的时候,保持悲观态度。总是认为数据会被其他事务修改,所以每次操作数据的时候,都会被数据上锁,使别他事务操作数据的时候处于阻塞状态,知道释放锁,保证数据具有排他性。
  • 行锁、表锁、读锁、写锁就是悲观锁的体现,每次在操作数据的时候,都会加锁,使其他数据在访问的时候被阻塞挂起,直到释放锁。
  • 其实悲观锁的使用场景并不是很多,因为它在每次操作的时候,都会给数据上锁,这样会在事务比较长的时候,性能会比较差。
  • 悲观锁的适用场景是写操作多的情况下,因为写具有排他性,在写操作的时候,阻止其他事务对数据的读或写的操作,这样很大的避免了读-写/写-读的冲突,进而避免了脏读、不可重复读、幻读的问题。

7.2 乐观锁

乐观锁,就是对数据的操作持有乐观的态度,任务每次操作数据时,都不会有其他的事务对数据进行修改操作。但是在每次一修改数据的时候,都会判断在此期间数据是否被其他事务修改过。

乐观锁是在操作数据的时候,通过程序来进行控制的,比如:使用版本号,或者时间戳来进行比对。

  • 版本号的乐观锁: 在数据表中,添加一个字段’version’,这个字段使用来记录每次数据跟新后的数据版本。在进行数据的更新操作时,会先拿到’version’字段的值,更新数据的时候,会拿之前的version的值和现在数据库里面的‘version’进行比较,如果两个‘version’的值是一样的,说明在此期间数据没有被修改过,可以进行更新操作。反过来,如果两个‘version’的值不一样,说明此期间有其他事务修改过这条记录,则更新失败。
  • 在更新数据的时候,会使’version’的值加1。
`UPDATE student SET name= '李四' ,version=version+1 WHERE version=version` 

乐观锁的适用场景读多写少的场景,由程序实现,不会出现死锁问题。

7.3 总结

到此这篇关于MySQL 数据库锁的实现的文章就介绍到这了,更多相关MySQL 数据库锁内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

您可能感兴趣的文档:

--结束END--

本文标题: MySQL数据库锁的实现

本文链接: https://www.lsjlt.com/news/200552.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • MySQL数据库锁的实现
    目录1.什么是锁2.锁解决的问题3.并发访问相同记录的几种情况4.理解读锁和写锁4.1 读锁4.2 写锁5.表锁5.1 表级的读/写锁5.2 意向锁6.行锁6.1 记录锁6.2 间隙...
    99+
    2023-03-20
    MySQL 数据库锁 MySQL
  • MySQL 数据库锁的实现
    目录1.什么是锁2.锁解决的问题3.并发访问相同记录的几种情况4.理解读锁和写锁4.1 读锁4.2 写锁5.表锁5.1 表级的读/写锁5.2 意向锁6.行锁6.1 记录锁6.2 间隙锁6.3 临界锁7.悲观锁和乐观锁7....
    99+
    2023-03-20
    MySQL 数据库锁 MySQL
  • MySQL数据库锁如何实现
    这篇“MySQL数据库锁如何实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“MySQL数...
    99+
    2023-03-23
    mysql
  • MySQL数据库中怎么实现全局锁和表级锁
    这篇文章给大家介绍MySQL数据库中怎么实现全局锁和表级锁,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。1. 全局锁全局锁是粒度比较大的锁,基本上也使用不上,就像我们家的大门一样,控制...
    99+
    2024-04-02
  • MYSQL数据库Innodb 引擎mvcc锁实现原理
    目录1 数据库设置隔离级别2 数据库表以及案例操作3 mvcc 实现原理4 ACID 的实现前言: 大家都知道在java 开发过程中,会经常用到锁,在java 代码中,我们都知道锁是...
    99+
    2024-04-02
  • 数据库的乐观锁如何实现
    本文小编为大家详细介绍“数据库的乐观锁如何实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“数据库的乐观锁如何实现”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。线程锁分类有很多...
    99+
    2024-04-02
  • 【数据库】MySQL中的锁机制
    MySQL中的锁机制 数据库锁定机制简单来说,就是数据库为了保证数据的一致性,而使各种共享资源在被并发访问变得有序所设计的一种规则。 MySQL 数据库由于其自身架构的特点,存在多种数据存储引擎,每种存储引擎的锁定机制都是为各...
    99+
    2023-08-18
    mysql 锁机制 共享锁 排它锁
  • 怎么在MySQL数据库中实现一个分布式锁
    这篇文章将为大家详细讲解有关怎么在MySQL数据库中实现一个分布式锁,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。建表CREATE TABLE&n...
    99+
    2024-04-02
  • MySQL数据库中有哪些锁
    这篇文章主要介绍“MySQL数据库中有哪些锁”,在日常操作中,相信很多人在MySQL数据库中有哪些锁问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”MySQL数据库中有哪些锁”...
    99+
    2024-04-02
  • 主流关系数据库锁实现的区别
    SQL Server实现的锁主要是由通过锁表来实现,在内存中开辟专门区域对于不同级别的对象(行、键-块-对象、索引-库)相应的锁记录,事务层和存储层完全分离,并且锁占用开销较大,当锁占用较多资源的时候,会进...
    99+
    2024-04-02
  • 如何锁定MySQL数据库表
    本篇文章给大家分享的是有关如何锁定MySQL数据库表,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。  如何锁定MySQL数据库表  锁定表的方...
    99+
    2024-04-02
  • MySQL数据库的锁机制是什么
    本篇内容介绍了“MySQL数据库的锁机制是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!为什么要加锁?...
    99+
    2024-04-02
  • mysql数据库怎么实现
    mysql数据库实现步骤:安装mysql服务器;创建数据库;创建用户并授予权限;连接到数据库;创建表;插入数据;查询数据;修改数据;删除数据;备份数据库。 MySQL数据库实现 如何实...
    99+
    2024-04-22
    mysql 数据丢失
  • JavaWeb实现显示mysql数据库数据
    目录EMS-员工信息管理系统创建ems库创建user表插入表格数据创建UserListServlets使用JDBC连接数据库部署服务器EMS-员工信息管理系统 MySQL学习之基础操...
    99+
    2024-04-02
  • 抽取oracle数据到mysql数据库的实现
    这篇文章给大家介绍抽取oracle数据到mysql数据库的实现,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。1、要抽取mysql表、字段及过滤条件的配制文件imp_data.sql2、...
    99+
    2024-04-02
  • Python操作Mysql数据库的实现
    1、需要使用的模块MySQLdb,下载地址为:http://sourceforge.net/projects/mysql-python/2、实现代码如下:#!/usr/bin/env python # encoding: utf-8 im...
    99+
    2023-01-31
    操作 数据库 Python
  • mysql数据库锁表怎么解决
    mysql数据库中出现锁表的解决方法:1.启动mysql;2.登录mysql数据库;3.进入数据表;4.查询锁表的进程;5.使用KILL命令删除进程;具体步骤如下:首先,在命令行中启动mysql服务;sudo service mysql s...
    99+
    2024-04-02
  • mysql数据库锁机制是什么
    小编给大家分享一下mysql数据库锁机制是什么,希望大家阅读完这篇文章后大所收获,下面让我们一起去探讨吧!并发控制数据库管理系统中的并发控制的任务是确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性...
    99+
    2024-04-02
  • PHP实现获取MySQL数据库的记录数据
    目录如果后台数据处理使用PHP来进行,那么就要有相应的数据处理及返回。 最常用的就是获取记录总数和表记录查询结果。 获取数据表的记录总数 <php require 'linkC...
    99+
    2024-04-02
  • ​MySQL数据库中的锁有哪些类型
    这篇文章给大家分享的是有关MySQL数据库中的锁有哪些类型的内容。小编觉得挺实用的,因此分享给大家做个参考。一起跟随小编过来看看吧。MySQL数据库中的锁有共享锁,排他锁,行锁,表级锁,行级锁以及页面锁。1...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作