0

0

关于MySQL涉及锁的问题详解

藏色散人

藏色散人

发布时间:2020-03-29 09:03:10

|

2151人浏览过

|

来源于cnblogs

转载

如何并发的访问数据库呢?答案就是加锁

推荐:《mysql视频教程

接下来说一下,数据库的锁机制,数据库中都有哪些锁?

  首先呢,锁是一种并发控制技术,锁是用来在多个用户同时访问同一个数据的时候保护数据的。

有2种基本的锁类型:

  共享(S)锁:多个事务可封锁一个共享页;任何事务都不能修改该页;通常是该页被读取完毕,S锁立即被释放。在执行select语句的时候需要给操作对象(表或一些记录)加上共享锁,但加锁之前需要检查是否有排他锁,如果没有,则可以加共享锁(一个对象上可以加N个共享锁),否则不行。共享锁通常在执行完select语句之后被释放,当然也可能是在事务结束(包括正常结束和异常结束)的时候被释放,主要取决与数据库所设置的事务隔离级别。

  排它(X)锁:仅允许一个事务封锁此页;其他任何事务必须等到X锁被释放才能对该页进行访问;X锁一直到事务结束才能被释放。执行insert、update、delete语句的时候需要给操作的对象加排它锁,在加排他锁之前必须确认该对象上没有其他任何锁,一旦加上排它锁之后,就不能再给这个对象加其他任何锁。排它锁的释放通常是在事务结束的时候(当然也有例外,就是在数据库事务隔离级别被设置为Read Uncommitted(读未提交数据)的时候,这种情况下排他锁会在执行完更新操作之后被释放,而不是在事务结束的时候)。

按锁的机制

既然使用了锁,就有出现死锁的可能。

产生死锁的四个必要条件:

  互斥条件:一个资源每次只能被一个进程使用。

  请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。

  不可剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺。

  环路等待条件:若干个进程之间形成一种头尾相接的循环等待资源关系。

只要系统发生了死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。

预防死锁

预防死锁的发生只需要破坏死锁产生的四个必要条件之一即可。

1)破坏互斥条件

  如果允许系统资源都能共享使用,则系统不会进入死锁状态。但有些资源根本不能同时访问,如打印机等临界资源只能互斥使用。所以破坏互斥条件而预防死锁的方法不太可行,而且在有些场合应该保护这种互斥性。

2)破坏不可剥夺条件

  当一个已保持了某些不可剥夺资源的进程,请求新的资源而得不到满足时,它必须释放已经保持的所有资源,待以后需要时再重新申请。这意味着,一个进程已占有的资源会被暂时释放,或者说是被剥夺了,或从而破坏了不可剥夺条件。

  该策略实现起来比较复杂,释放已获得的资源可能造成前一阶段工作的失效,反复地申请和释放资源会增加系统开销,降低系统吞吐量。这种方法常用于状态易于保存和恢复的资源,如CPU的寄存器及内存资源,一般不能用于打印机之类的资源。

3)破坏请求和保持的条件

  采用预先静态分配方法,即进程在运行前一次申请完它所需要的全部资源,在它的资源为满足前,不把它投入运行。一旦投入运行后,这些资源就一直归它所有,也不再提出其他资源请求,这样就可以保证系统不会发生死锁。

  这种方式实现简单,但缺点也显而易见,系统资源被严重浪费,其中有些资源可能仅在运行初期或运行快结束时才使用,甚至根本不使用。而且还会导致“饥饿”现象,当由于个别资源长期被其他进程占用时,将致使等待该资源的进程迟迟不能开始运行。

4)破坏环路等待条件

  为了破坏环路等待条件,可采用顺序资源分配法。首先给系统中的资源编号,规定每个进程,必须按编号递增的顺序请求资源,同类资源一次申请完。也就是说,只要进程提出申请分配资源Ri,则该进程在以后的资源申请种,只能申请编号大于Ri的资源。

  这种方法存在的问题时,编号必须相对稳定,这就限制了新类型设备的增加;尽管在为资源编号时已考虑到大多数作业实际使用这些资源的顺序,但也经常会发生作业使用资源的顺序与系统规定顺序不同的情况,造成资源的浪费;此外,这种按规定次序申请资源的方法,也必然会给用户的编程带来麻烦。

解除死锁

  1)从死锁进程处剥夺资源;

  2)终止部分或全部进程;

聚好用AI
聚好用AI

可免费AI绘图、AI音乐、AI视频创作,聚集全球顶级AI,一站式创意平台

下载

MySQL锁的粒度(即锁的级别)

MySQL各存储引擎使用了三种类型(级别)的锁定机制:行级锁定、页级锁定和表级锁定。

  1、表级锁:直接锁定整张表,在你锁定期间,其他进程无法对该表进行写操作。如果你是写锁,则其他进程则读也不允许。特点:开销小,加锁快;不会出现死锁;锁粒度最大,发生锁冲突的概率最高,并发度最低。

    MyISAM存储引擎采用的是表级锁。

    有两种模式:表共享读锁和表独占写锁。加读锁的命令:lock table 表名 read;  去掉锁的命令:unlock tables。

    支持并发插入:支持查询和插入操作并发运行(在表尾并发插入)。

    锁调度机制:写锁优先。一个进程请求某个MyISAM表的读锁,同时另一个进程也请求同一表的写锁,MySQL如何处理呢?答案是写进程先获得锁。

  2、行级锁:仅对指定的记录进行加锁,这样其他进程还是可以对同一个表中的其他记录进行操作。特点:开销大,加锁慢;会出现死锁;锁粒度最小,发生锁冲突的概率最低,并发度也最高。

    InnoDB存储引擎既支持行级锁,也支持表级锁,但默认情况下是采用行级锁。

  3、页级锁:一次锁定相邻的一组记录。开销和加锁时间介于表锁和行锁之间;会出现死锁;锁定粒度介于表锁和行锁治安,并发度一般。

  最常用的处理多用户并发访问的方法是加锁。当一个用户锁定数据库中的某个对象时,其他用户就不能再访问该对象。加锁对并发访问的影响体现在锁的粒度上。比如,(表锁)放在一个表上的锁限制对整个表的并发访问;(页锁)放在数据页上的锁限制了对整个数据页的访问;(行锁)放在行上的锁只限制对该行的并发访问。

乐观锁和悲观锁的概念,实现方式和使用场景

锁有两种机制:悲观锁和乐观锁。

  悲观锁,锁如其名,它对世界是悲观的,它认为别人访问正在改变的数据的概率是很高的,所以从数据开始更改时就将数据锁住,直到更改完成才释放。

一个典型的依赖数据库的悲观锁调用:

  select * from account where name="Erica" for update

  这条SQL语句锁定了account表中所有符合检索条件(name="Erica")的记录。本事务提交之前(事务提交时会释放事务过程中的锁),外界无法修改这些记录。该语句用来锁定特定的行(如果where子句,就是满足where条件的那些行)。当这些行被锁定后,其他会话可以选择这些行,但不能更改或删除这些行,直到该语句的事务被commit语句或rollback语句结束终止。需要注意的是,select ...for update要放到MySQL的事务种,即begin和commit中,否则不起作用。

  悲观所可能会造成加锁的时间很长,并发行不好,特别是长事务,影响系统的整体性能。

  悲观所的实现方式:

    悲观锁,也是基于数据库的锁机制实现。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁、写锁等,都是在做操作之前先上锁。

  乐观锁,它对世界比较乐观,认为别人访问正在改变的数据的概率是很低的,所以直到修改完成准备提交所作的修改到数据库的时候才会将数据锁住,当你读取以及改变该对象时并不加锁,完成更改后释放。乐观锁不能解决脏读的问题。

  乐观锁加锁的时间要比悲观锁短,大大提升了大并发量下的系统整体性能表现。

  乐观锁的实现方式:

    1、大多是基于数据版本(version)记录机制实现,需要为每一行数据增加一个版本标识(也就是每一行数据多一个字段version),每次更新数据都要更新对应的版本号+1。

    工作原理:读出数据时,将此版本一同读出,之后更新时,对此版本号加一。此时,将提交的数据的版本信息与数据库表对应记录的当前版本信息进行比对,如果提交的数据版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据,不得不重新读取该对象并作出更改。

    2、使用时间戳来实现

    同样是在需要乐观锁控制的table中增加一个字段,名称无所谓,字段类型使用时间戳(timestamp),和上面的version类似,也是在更新提交的时候检查当前数据库中数据的时间戳和自己更新前取到的时间戳进行对比,如果一致则OK,否则就是版本冲突。

悲观锁与乐观锁的适用场景:

  如果并发量不大,可以使用悲观锁解决并发问题;但如果系统的并发量非常大的话,悲观所定会带来非常大的性能问题,所以我们就要选择乐观锁定的方法。现在大部分应用都应该是乐观锁的。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

49

2026.03.13

Python异步编程与Asyncio高并发应用实践
Python异步编程与Asyncio高并发应用实践

本专题围绕 Python 异步编程模型展开,深入讲解 Asyncio 框架的核心原理与应用实践。内容包括事件循环机制、协程任务调度、异步 IO 处理以及并发任务管理策略。通过构建高并发网络请求与异步数据处理案例,帮助开发者掌握 Python 在高并发场景中的高效开发方法,并提升系统资源利用率与整体运行性能。

89

2026.03.12

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

276

2026.03.11

Go高并发任务调度与Goroutine池化实践
Go高并发任务调度与Goroutine池化实践

本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

59

2026.03.10

Kotlin Android模块化架构与组件化开发实践
Kotlin Android模块化架构与组件化开发实践

本专题围绕 Kotlin 在 Android 应用开发中的架构实践展开,重点讲解模块化设计与组件化开发的实现思路。内容包括项目模块拆分策略、公共组件封装、依赖管理优化、路由通信机制以及大型项目的工程化管理方法。通过真实项目案例分析,帮助开发者构建结构清晰、易扩展且维护成本低的 Android 应用架构体系,提升团队协作效率与项目迭代速度。

99

2026.03.09

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

105

2026.03.06

Rust内存安全机制与所有权模型深度实践
Rust内存安全机制与所有权模型深度实践

本专题围绕 Rust 语言核心特性展开,深入讲解所有权机制、借用规则、生命周期管理以及智能指针等关键概念。通过系统级开发案例,分析内存安全保障原理与零成本抽象优势,并结合并发场景讲解 Send 与 Sync 特性实现机制。帮助开发者真正理解 Rust 的设计哲学,掌握在高性能与安全性并重场景中的工程实践能力。

230

2026.03.05

PHP高性能API设计与Laravel服务架构实践
PHP高性能API设计与Laravel服务架构实践

本专题围绕 PHP 在现代 Web 后端开发中的高性能实践展开,重点讲解基于 Laravel 框架构建可扩展 API 服务的核心方法。内容涵盖路由与中间件机制、服务容器与依赖注入、接口版本管理、缓存策略设计以及队列异步处理方案。同时结合高并发场景,深入分析性能瓶颈定位与优化思路,帮助开发者构建稳定、高效、易维护的 PHP 后端服务体系。

619

2026.03.04

AI安装教程大全
AI安装教程大全

2026最全AI工具安装教程专题:包含各版本AI绘图、AI视频、智能办公软件的本地化部署手册。全篇零基础友好,附带最新模型下载地址、一键安装脚本及常见报错修复方案。每日更新,收藏这一篇就够了,让AI安装不再报错!

173

2026.03.04

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
MySQL 教程
MySQL 教程

共48课时 | 2.6万人学习

MySQL 初学入门(mosh老师)
MySQL 初学入门(mosh老师)

共3课时 | 0.3万人学习

简单聊聊mysql8与网络通信
简单聊聊mysql8与网络通信

共1课时 | 850人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号