MyBatis-Plus如何娴熟运用乐观锁

欢迎来到我的博客,代码的世界里,每一行都是一个故事


在这里插入图片描述

MyBatis-Plus如何娴熟运用乐观锁

    • 前言
    • 乐观锁的基本概念
      • 基本概念和原理:
      • 为何乐观锁是解决并发问题的有效手段:
    • MyBatis-Plus中乐观锁的支持
      • 1. `@Version` 注解:
      • 2. 配置乐观锁插件:
      • 3. 更新操作:
      • 注意事项:
    • 乐观锁的使用场景
    • 版本号和时间戳的选择
      • 版本号:
        • 优势:
        • 劣势:
      • 时间戳:
        • 优势:
        • 劣势:

前言

在数据库操作中,数据的一致性与并发性是一对不可忽视的矛盾。然而,MyBatis-Plus如今有了一项强大的工具——乐观锁,让我们在并发的世界中保持数据的完整性。本文将带你走进这个数据的乐章,探索乐观锁的魅力。

乐观锁的基本概念

乐观锁是一种用于处理并发访问的机制,其基本原理是在不加锁的情况下进行操作,但在更新数据时会先检查其他线程是否对数据进行了修改。乐观锁假定在大多数情况下,数据不会有冲突的修改,因此尝试直接进行操作,只在发现冲突时再采取适当的措施。

基本概念和原理:

  1. 版本号或时间戳: 乐观锁通常会在数据表中引入一个版本号或时间戳字段,用于标识数据的版本信息。

  2. 读取和修改操作: 当一个线程要更新数据时,它首先会读取数据的当前版本号。在执行更新操作前,线程会再次检查数据的版本号,确保在读取数据到实际更新之间,其他线程没有对同一数据进行修改。

  3. 比较和更新: 如果在执行更新操作前,数据的版本号没有发生变化,那么该线程认为操作是合法的,然后执行更新操作,并将版本号加一(或更新为当前时间戳)。

  4. 冲突检测: 如果在比较版本号时发现数据的版本号已经发生了变化,说明其他线程已经修改了该数据,那么当前线程会根据业务需要,选择合适的处理方式,例如进行重试、回滚操作或者抛出异常。

为何乐观锁是解决并发问题的有效手段:

  1. 减少锁竞争: 乐观锁避免了在读取数据和执行更新操作之间的长时间锁定,因为大多数情况下,数据并没有被其他线程修改。

  2. 提高并发性能: 由于乐观锁避免了大部分的锁冲突,多个线程可以同时读取数据,并在需要时进行相应的冲突检测和处理,从而提高了系统的并发性能。

  3. 降低死锁风险: 由于乐观锁的操作不涉及到锁的获取和释放,因此减少了死锁的风险。

  4. 适用于高并发环境: 在高并发的场景中,乐观锁更容易适应大量读操作和较少写操作的情况,提高了系统的整体效率。

  5. 支持乐观并发控制: 乐观锁为乐观并发控制(Optimistic Concurrency Control)提供了实现基础,是许多分布式数据库和缓存系统的实现方式之一。

尽管乐观锁在大多数情况下表现良好,但在高并发写入的场景下,冲突检测和处理的开销可能会增加,因此在选择锁策略时需要根据具体业务场景权衡各种因素。

MyBatis-Plus中乐观锁的支持

MyBatis-Plus 是基于 MyBatis 的增强工具,在支持 MyBatis 的基础上提供了更多的功能和方便的 API。对于乐观锁的支持,MyBatis-Plus 提供了 @Version 注解和相应的配置。

以下是 MyBatis-Plus 中乐观锁的支持方式:

1. @Version 注解:

在实体类的版本字段上使用 @Version 注解,表示该字段为乐观锁字段。该注解告诉 MyBatis-Plus 在更新操作时要进行版本号的自动增加。

import com.baomidou.mybatisplus.annotation.Version;

public class User {
    // 其他字段...

    @Version
    private Integer version; // 版本号字段
}

2. 配置乐观锁插件:

在 MyBatis-Plus 的配置文件(一般是 mybatis-plus-config.xml 或者通过 MybatisPlusInterceptor 配置)中开启乐观锁插件。

<!-- mybatis-plus-config.xml -->
<configuration>
    <!-- 其他配置... -->
    
    <plugins>
        <!-- 乐观锁插件 -->
        <plugin interceptor="com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor"/>
    </plugins>
</configuration>

或者使用 Java 配置:

@Configuration
public class MybatisPlusConfig {

    @Bean
    public OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor() {
        return new OptimisticLockerInnerInterceptor();
    }
}

3. 更新操作:

在执行更新操作时,MyBatis-Plus 会自动检测是否存在 @Version 注解,并在更新时自动增加版本号。

@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;

    public void updateUser(User user) {
        int result = userMapper.updateById(user);
        if (result == 0) {
            // 更新失败,可能是版本号不匹配
            // 处理冲突逻辑...
        }
    }
}

在这个例子中,updateById 是 MyBatis-Plus 提供的根据主键更新数据的方法,乐观锁的版本号会在执行更新时自动增加。

注意事项:

  1. 乐观锁字段的类型通常为整数类型(例如 intIntegerlongLong 等),因为乐观锁是通过版本号的增加来实现的。

  2. MyBatis-Plus 会在 SQL 的 UPDATE 语句中自动增加版本号的判断条件,确保只有版本号匹配的记录才会被更新。

  3. 在处理更新失败时,可以根据具体业务需求进行相应的处理,例如重试、回滚操作等。

通过以上配置和注解,MyBatis-Plus 提供了便捷的乐观锁支持,简化了开发者对乐观锁的使用和管理。

乐观锁的使用场景

乐观锁适用于一些特定的场景,其中读操作相对频繁,而写操作相对较少,从而减少了对数据库表的长时间锁定,提高了并发性能。以下是一些乐观锁适用的场景:

  1. 读多写少的场景: 当一个系统中读操作远远多于写操作时,使用乐观锁可以避免对数据进行长时间的锁定,提高了并发性能。

  2. 短事务: 在需要执行短事务的场景中,乐观锁可以更好地适应。悲观锁可能会导致长时间的事务锁定,而乐观锁则通过冲突检测的方式更加灵活。

  3. 业务逻辑相对简单: 乐观锁对业务逻辑相对简单的场景更为适用。在复杂业务逻辑下,需要考虑更多的冲突检测和处理逻辑。

  4. 不同事务频繁访问不同数据: 如果事务频繁访问不同的数据,悲观锁可能会导致性能下降。而乐观锁通过版本号或时间戳进行冲突检测,相对更加轻量。

在实际项目中选择使用乐观锁时,可以考虑以下因素:

  1. 并发性能需求: 如果系统具有较高的并发性能需求,并且读操作远多于写操作,考虑使用乐观锁。

  2. 事务长度: 如果事务需要保持短时间内的锁定,乐观锁可能更适合。对于长时间的事务,悲观锁可能更为合适。

  3. 业务复杂度: 乐观锁相对简单,适用于业务逻辑相对简单的场景。在业务逻辑复杂、涉及多个事务的情况下,需要更仔细地考虑锁策略。

  4. 冲突处理策略: 了解并考虑冲突处理策略。当发生冲突时,系统应该如何处理,是否需要重试、回滚、记录冲突等。

在具体项目中,选择使用乐观锁还是悲观锁,取决于具体的业务需求、并发性能要求以及系统架构。在使用乐观锁时,要确保冲突检测和处理是正确且安全的,以维护数据的一致性。

版本号和时间戳的选择

选择使用版本号还是时间戳(Timestamp)作为乐观锁的依据主要取决于具体的业务需求、数据特性以及系统设计的考虑。以下是版本号和时间戳的优劣势以及适用场景:

版本号:

优势:
  1. 简单直观: 版本号通常是整数类型,使用简单直观。在数据库中,可以使用整型字段表示版本号。

  2. 性能: 整数比时间戳在存储和比较上更为高效,因此在一些对性能要求较高的场景中,版本号可能更适合。

  3. 逻辑上的顺序性: 版本号是递增的整数,有一定的逻辑上的顺序性,方便在业务层面进行理解。

劣势:
  1. 不易回溯: 版本号通常只能表达相对顺序,但难以精确表示某个操作的时间点。

  2. 不支持跨系统时间比较: 版本号无法在分布式系统中做到精确的时间比较。

时间戳:

优势:
  1. 精确记录时间: 时间戳可以精确记录数据的最后更新时间,提供更丰富的时间信息,方便进行数据审计和分析。

  2. 支持跨系统时间比较: 时间戳更容易在分布式系统中进行比较,确保全局有序性。

劣势:
  1. 存储和比较相对复杂: 时间戳通常是长整型或日期时间类型,在存储和比较上相对于整数来说更为复杂,可能会对性能产生一些影响。

  2. 时间精度问题: 在某些系统中,时间戳的精度可能不足以满足需求,例如需要毫秒级别的精度。

综合考虑,选择版本号还是时间戳取决于项目的具体需求:

  • 如果系统对性能有较高要求,而且业务逻辑对时间精度要求不高,使用版本号可能更为适合。

  • 如果系统需要更丰富的时间信息,例如进行审计或有强烈的时间先后关系要求,使用时间戳可能更为合适。

  • 在一些项目中,甚至可以同时使用版本号和时间戳,充分发挥它们各自的优势。例如,版本号用于快速比较和冲突检测,时间戳用于记录具体的时间信息。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

穿越牛熊,股市的春天还有多远?

2023年&#xff0c;资本市场的严冬令无数投资者和机构投资者都感受到了前所未有的压力。VC/PE、公募基金、股权投资类公司等机构&#xff0c;在这一年里业绩普遍不佳&#xff0c;寒意弥漫。VC/PE机构的营业收入普遍呈现负增长&#xff0c;公募基金更是历史上首次连续两年亏损&a…

包含字母数字及特殊字符 三种组合的正则两种写法

//长度8~16位&#xff1b;包含字母、数字及特殊字符 #$%^&*_-//正则1 写法&#xff1a;let reg_1 /^(?![A-Za-z0-9]$)^(?![A-Za-z#$\%^&*_\-]$)^(?![0-9#$\%^&_*\-]$)([A-Za-z0-9#$\%^&*_\-]{8,16})$///正则2 写法&#xff1a;let reg_2 /^(?![A-Za-z#$%…

在Vue中处理接口返回的二进制图片数据

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

产品经理必看,教你写一份简单的产品说明书

作为一名产品经理&#xff0c;你可能会为如何写一份能够有效传达产品特性和使用步骤的说明书而困扰。确实&#xff0c;写作产品说明书的过程中&#xff0c;需要详细并准确展示产品的所有功能&#xff0c;同时保持文本清晰、简洁和易于理解。以下是一些步骤和技巧&#xff0c;可…

AntV L7的pointLayer点图层

本案例使用L7库和Mapbox GL JS创建点数据并加载进地图。 文章目录 1. 引入 CDN 链接2. 引入组件3. 创建地图4. 创建场景5. 创建点数据5.1. 普通 json 数据5.2. geojson 数据 6. 创建点图层6.1. 普通 json 数据6.2. geojson 数据 7. 演示效果8. 代码实现 1. 引入 CDN 链接 <s…

不注册访问 Claude3 大模型

随着Claude3大模型的出世&#xff0c;大模型霸主地位已经发生易位&#xff0c;但是国内使用Claude3官网 无论是注册都不容易&#xff0c;本篇文章主要介绍如何不通过Claude3 官网实现Claude3 大模型的使用&#xff0c;这里优先推荐Chatbot Arena 一、直接通过第三方代理 Chatb…

CorelDRAW Graphics Suite2024免费试用体验15天版下载

使用基于全球知名的 Corel Painter 画笔技术构建的 100 款逼真像素画笔&#xff0c;以全新的方式将您独特的想法变为现实&#xff01;试用 CorelDRAW 的全新美术画笔&#xff0c;探索您的创意想法。 使用 CorelDRAW 中现在可用的远程字体&#xff0c;畅享更多创作自由&#xf…

Humanoid-Gym 开源人形机器人端到端强化学习训练框架!星动纪元联合清华大学、上海期智研究院发布!

系列文章目录 前言 Humanoid-Gym: Reinforcement Learning for Humanoid Robot with Zero-Shot Sim2Real Transfer GitHub Repository: GitHub - roboterax/humanoid-gym: Humanoid-Gym: Reinforcement Learning for Humanoid Robot with Zero-Shot Sim2Real Transfer 一、介…

一键查看:大厂网站都用了啥技术栈,有图有真相。

本次我们采用Wappalyzer插件来看下国内大厂的网站都采用了什么技术架构&#xff0c;文章最后由Wappalyzer的安装方法。 今日头条网站 淘宝网站 哔哩哔哩 京东商城 花瓣网 CSDN 国务院 网易 58同城 腾讯网 如何安装Wappalyzer 用Edge浏览器即可

软考70-上午题-【面向对象技术2-UML】-UML中的图1

一、图的定义 图是一组元素的图形表示&#xff0c;大多数情况下把图画成顶点、弧的联通图。 顶点&#xff1a;代表事物&#xff1b; 弧&#xff1a;代表关系。 可以从不同的角度画图&#xff0c;UML提供了13种图&#xff1a;&#xff08;只看9种&#xff09; 类图&#xff…

内联函数|auto关键字|范围for的语法|指针空值

文章目录 一、内联函数1.1概念1.2特性 二、auto关键字2.2类型别名思考2.3auto简介2.4auto使用细则2.4 auto不能推导的场景 三、基于范围的for循环(C11)3.1 范围for的语法 四、指针空值nullptr(C11)4.1 C98中的指针空值 所属专栏:C初阶 一、内联函数 1.1概念 以inline修饰的函…

内部订单预算管理 在建工程项目结转流程以及用户操作步骤

业务流程概述: 所有的内部定单(项目)在月底时都必须将当月发生的费用按结算规则结转到在建工程卡片中。为保证结转的正确性,在系统中可以先查看项目费用的明细表后再由系统自动结转到在建工程卡片中。 对于已竣工的项目,还需要到系统中查看项目报表,根据报表将工程实际发生…

【人工智能入门必看的最全Python编程实战(2)】

4.4.2 复合语句&#xff1a; if语句&#xff0c;当条件成立时执行语句包。它经常包含elif、else子句。while语句&#xff0c;当条件为真时&#xff0c;重复执行语句包。for语句&#xff0c;遍历列表、字符串、字典、集合等迭代器&#xff0c;依次处理迭代器中的每个元素。matc…

设计模式——2_4 中介者(Mediator)

我寄愁心与明月&#xff0c;随风直到夜郎西 ——李白《闻王昌龄左迁龙标遥有此寄》 文章目录 定义图纸一个例子&#xff1a;怎么调度一组地铁站台和地铁开车指挥中心 碎碎念中介者和表单平台思想但是这种平台便利性是要付出代价的变化隔离原则 姑妄言之 定义 用一个中介者对象…

吴恩达机器学习-可选实验室:特征工程和多项式回归(Feature Engineering and Polynomial Regression)

文章目录 目标工具特征工程和多项式回归概述多项式特征选择功能备用视图扩展功能复杂的功能 恭喜! 目标 在本实验中&#xff0c;你将:探索特征工程和多项式回归&#xff0c;它们允许您使用线性回归的机制来拟合非常复杂&#xff0c;甚至非常非线性的函数。 工具 您将利用在以…

PageHelper 又给我上了一课!

多年不用PageHelper了&#xff0c;最近新入职的公司&#xff0c;采用了此工具集成的框架&#xff0c;作为一个独立紧急项目开发的基础。项目开发起来&#xff0c;还是手到擒来的&#xff0c;但是没想到&#xff0c;最终测试的时候&#xff0c;深深的给我上了一课。 # 我的项目发…

SpringCloud-SpringBoot读取Nacos上的配置文件

在 Spring Boot 应用程序中&#xff0c;可以使用 Spring Cloud Nacos 来实现从 Nacos 服务注册中心和配置中心读取配置信息。以下是如何在 Spring Boot 中读取 Nacos 上的配置文件的步骤&#xff1a; 1. 引入依赖 首先&#xff0c;在 Spring Boot 项目的 pom.xml 文件中添加 …

2007-2022年上市公司迪博内部控制评价缺陷数量数据

2007-2022年上市公司迪博内部控制评价缺陷数量数据 1、时间&#xff1a;2007-2022年 2、范围&#xff1a;上市公司 3、指标&#xff1a;证券代码、证券简称、辖区、证监会行业、申万行业、是否存在财报内控重大缺陷、财报内控重大缺陷数量、是否存在财报内控重要缺陷、财报内…

亚信安慧AntDB:“融合+实时”引领数据库创新

在当今多变的数据应用场景中&#xff0c;AntDB作为行业领先的超融合流式实时数仓&#xff0c;秉承着“融合实时”的研发理念&#xff0c;全面应对企业日益复杂的数据处理需求。通过SQL接口访问多种执行引擎&#xff0c;AntDB在实现交易、分析等多重能力的“超融合”方面取得了显…