数据库的乐观锁和悲观锁

news2025/3/6 9:44:35

乐观锁(Optimistic Locking)

乐观锁是一种假设数据库操作不会发生冲突的锁定机制。在执行数据更新操作时,它并不会立刻加锁,而是先允许所有事务继续执行,并在提交时检查数据是否发生了变化。如果数据在读取后被其他事务修改了,那么当前事务就会被阻止,并给出一个冲突的提示。

乐观锁的使用场景:

  • 在并发冲突较少的环境中使用,适合读多写少的场景。
  • 不需要过多地使用数据库锁,减少了资源消耗,提高了系统的效率。

工作原理:

  • 每一行数据都有一个版本号(Version)或者时间戳(Timestamp),它在每次更新时会被递增或更新。
  • 当一个事务准备提交时,它会检查该行数据的版本号是否发生了变化。如果版本号没有变化,则提交更新;如果版本号变化了,说明有其他事务修改了该数据,当前事务则会被回滚或抛出冲突异常。

乐观锁的实现:

  1. 通过版本号: 每条数据在数据库中有一个版本号字段,每次更新时都会检查版本号是否一致,若不一致则抛出异常。
SELECT * FROM account WHERE id = 1 AND version = 1;
UPDATE account SET balance = balance - 100, version = version + 1 WHERE id = 1 AND version = 1;
  1. 通过时间戳: 每条数据也可以通过时间戳来标识数据的修改时间,更新时验证修改时间是否一致。

优点:

  • 对性能影响小,资源占用少。
  • 可以并发处理,降低锁竞争。

缺点:

  • 在高并发情况下,冲突概率大时,回滚和重试的成本可能增加。

悲观锁(Pessimistic Locking)

悲观锁是一种假设数据库操作会发生冲突的锁定机制。在执行数据更新操作时,事务会先加锁,其他事务在锁释放之前不能访问被锁定的数据,从而保证数据一致性。悲观锁通常是在读取数据时就加锁,直到事务结束才释放锁。

悲观锁的使用场景:

  • 在并发冲突较多的环境中使用,适合写多读少的场景。
  • 数据一致性要求高的情况下,适合使用悲观锁来避免数据被并发修改。

工作原理:

  • 事务在访问数据时会给数据加锁,直到事务完成操作并提交,锁才会释放。其他事务在获取不到锁时会被阻塞,直到锁被释放。
  • 悲观锁在数据库中通常通过 SELECT FOR UPDATE 语句来实现。

悲观锁的实现:

  1. 行级锁(SELECT FOR UPDATE): 在查询数据时加上 FOR UPDATE 关键字,保证当前数据行在事务提交之前不能被其他事务修改。
SELECT * FROM account WHERE id = 1 FOR UPDATE;
UPDATE account SET balance = balance - 100 WHERE id = 1;
  1. 数据库管理系统(DBMS)自动加锁: 例如,MySQL的InnoDB存储引擎在事务进行时会自动加锁,直到事务提交或回滚。

优点:

  • 数据的冲突较少,避免了多次提交检查的开销。
  • 数据一致性得到了严格保证。

缺点:

  • 性能开销较大,可能导致死锁(特别是在多个事务同时进行时),并发性能差。
  • 需要合理的锁粒度和锁管理,否则可能造成资源浪费。

总结对比:

特点乐观锁悲观锁
锁的类型读时不加锁,更新时检查版本号或时间戳读取时就加锁,直到事务结束才释放锁
使用场景并发冲突少,读多写少的场景并发冲突多,写多读少的数据场景
实现方式通过版本号、时间戳等方式实现通过行级锁(SELECT FOR UPDATE)等实现
性能开销性能较高,因为不加锁,只有提交时检查性能较低,可能导致阻塞和死锁
优点并发性能高,减少锁的竞争确保数据一致性,避免了冲突
缺点高并发情况下,回滚和重试的成本较高性能差,可能导致死锁和资源占用

在实际开发中,选择乐观锁还是悲观锁取决于具体的场景:

  • 对于冲突不频繁的场景(例如:库存、余额等),乐观锁是一个不错的选择;
  • 对于高并发的写入操作,且需要确保数据一致性的场景,悲观锁可能更适合。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2310479.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

react中如何使用使用react-redux进行数据管理

以上就是react-redux的使用过程,下面我们开始优化部分:当一个组件只有一个render生命周期,那么我们可以改写成一个无状态组件(UI组件到无状态组件,性能提升更好)

DeepSeek使用手册分享-附PDF下载连接

本次主要分享DeepSeek从技术原理到使用技巧内容,这里展示一些基本内容,后面附上详细PDF下载链接。 DeepSeek基本介绍 DeepSeek公司和模型的基本简介,以及DeepSeek高性能低成本获得业界的高度认可的原因。 DeepSeek技术路线解析 DeepSeek V3…

新品速递 | 多通道可编程衰减器+矩阵系统,如何破解复杂通信测试难题?

在无线通信技术快速迭代的今天,多通道可编程数字射频衰减器和衰减矩阵已成为测试领域不可或缺的核心工具。它们凭借高精度、灵活配置和强大的多通道协同能力,为5G、物联网、卫星通信等前沿技术的研发与验证提供了关键支持。从基站性能测试到终端设备校准…

Data truncation: Out of range value for column ‘allow_invite‘ at row 1

由于前端传递的数值超过了mysql数据库中tinyint类型的取值范围,所以就会报错。 Caused by: com.mysql.cj.jdbc.exceptions.MysqlDataTruncation: Data truncation: Out of range value for column allow_invite at row 1at com.mysql.cj.jdbc.exceptions.SQLExcept…

HCIA—IP路由静态

一、概念及作用 1、概念:IP路由是指在IP网络中,数据从源节点到目的节点所经过的路径选择和数据转发的过程。 2、作用 ①实现网络互联:使不同网段的设备能够相互通信,构建大规模的互联网络 ②优化网络拓扑:根据网络…

Hz的DP总结

前言: 鉴于本人是一个DP低手,以后每写一道DP都会在本篇博客下进行更新,包括解题思路,方法,尽量做到分类明确,其中的题目来自包括但并不限于牛客,洛谷,CodeForces,AtCode…

【三极管8050和8550贴片封装区分脚位】

这里写自定义目录标题 三极管8050和8550贴片封装区分脚位三极管8050三极管8550 三极管8050和8550贴片封装区分脚位 三极管8050 增加了 检查列表 功能。 [ NPN型三极管(SS8050) ]: SS8050的使用及引脚判断方法 三极管8550

C# Unity 唐老狮 No.6 模拟面试题

本文章不作任何商业用途 仅作学习与交流 安利唐老狮与其他老师合作的网站,内有大量免费资源和优质付费资源,我入门就是看唐老师的课程 打好坚实的基础非常非常重要: 全部 - 游习堂 - 唐老狮创立的游戏开发在线学习平台 - Powered By EduSoho 如果你发现了文章内特殊的字体格式,…

二、Visual Studio2022配置OpenGL环境

文章目录 一、OpenGL库的下载二、OpenGL环境配置三、测试代码演示 一、OpenGL库的下载 OpenGL配置的库是GLFWGLAD ,GLFW 主要用于创建 OpenGL 窗口和管理输入;GLAD 主要用于加载 OpenGL 函数 GLFW下载地址 下载Windows的32bit版本即可。 下载完成解压如…

YOLOv8改进------------SPFF-LSKA

YOLOv8改进------------SPFF-LSKA 1、LSAK.py代码2、添加YAML文件yolov8_SPPF_LSKA.yaml3、添加SPPF_LSKA代码4、ultralytics/nn/modules/__init__.py注册模块5、ultralytics/nn/tasks.py注册模块6、导入yaml文件训练 1、LSAK.py代码 论文 代码 LSKA.py添加到ultralytics/nn/…

240 Vocabulary Words Kids Need to Know

《240 Vocabulary Words Kids Need to Know》是美国学乐出版社(Scholastic)推出的词汇学习系列练习册,专为美国小学阶段(G1-G6)设计,基于CCSS(美国共同核心州立标准)编写&#xff0c…

AI-Deepseek + PPT

01--Deepseek提问 首先去Deepseek问一个问题: Deepseek的回答: 在汽车CAN总线通信中,DBC文件里的信号处理(如初始值、系数、偏移)主要是为了 将原始二进制数据转换为实际物理值,确保不同电子控制单元&…

【五.LangChain技术与应用】【8.LangChain提示词模板基础:从入门到精通】

早上八点,你端着咖啡打开IDE,老板刚甩来需求:“做个能自动生成产品描述的AI工具”。你自信满满地打开ChatGPT的API文档,结果半小时后对着满屏的"输出结果不稳定"、"格式总出错"抓耳挠腮——这时候你真需要好好认识下LangChain里的提示词模板了。 一、…

LeetCode 718.最长重复子数组(动态规划,Python)

给两个整数数组 nums1 和 nums2 ,返回 两个数组中 公共的 、长度最长的子数组的长度 。 示例 1: 输入:nums1 [1,2,3,2,1], nums2 [3,2,1,4,7] 输出:3 解释:长度最长的公共子数组是 [3,2,1] 。 示例 2: 输…

python-leetcode-零钱兑换 II

518. 零钱兑换 II - 力扣(LeetCode) 这个问题是 完全背包问题 的一个变体,可以使用 动态规划 来解决。我们定义 dp[i] 为凑成金额 i 的硬币组合数。 思路: 定义 DP 数组 设 dp[i] 表示凑成金额 i 的组合数,初始化 dp[…

Sass 模块化革命:深入解析 @use 语法,打造高效 CSS 架构

文章目录 前言use 用法1. 模块化与命名空间2. use 中 as 语法的使用3. as * 语法的使用4. 私有成员的访问5. use 中with默认值6. use 导入问题总结下一篇预告: 前言 在上一篇中,我们深入探讨了 Sass 中 import 语法的局限性,正是因为这些问题…

利用Postman和Apipost进行API测试的实践与优化-动态参数

在实际的开发和测试工作中,完成一个API后对其进行简单的测试是一项至关重要的任务。在测试过程中,确保API返回的数据符合预期,不仅可以提高开发效率,还能帮助我们快速发现可能存在的问题。对于简单的API测试,诸如验证响…

【前端基础】Day 9 PC端品优购项目

目录 1. 品优购项目规划 1.1 网站制作流程 1.2 品优购项目整体介绍 1.3 学习目的 1.4 开发工具以及技术栈 1.5 项目搭建工作 1.6 网站favicon图标 1.7 网站TDK三大标签SEO优化 2. 品优购首页制作 2.1 常见模块类命名 2.2 快捷导航shortcut制作 2.3 header制作 2.4…

FFMPEG利用H264+AAC合成TS文件

本次的DEMO是利用FFMPEG框架把H264文件和AAC文件合并成一个TS文件。这个DEMO很重要,因为在后面的推流项目中用到了这方面的技术。所以,大家最好把这个项目好好了解。 下面这个是流程图 从这个图我们能看出来,在main函数中我们主要做了这几步&…

Linux搭建个人大模型RAG-(ollama+deepseek+anythingLLM)

本文是远程安装ollama deepseek,本地笔记本电脑安装anythingLLM,并上传本地文件作为知识库。 1.安装ollama 安装可以非常简单,一行命令完事。(有没有GPU,都没有关系,自动下载合适的版本) cd 到…