当前位置: 首页 > web >正文

支付场景下,乐观锁的实现(简洁版)

1、问题描述

看到一个同事建的数据库表,好奇打开看看。

 
create table db_paycenter.t_pay_order_divide
(id           bigint auto_increment comment '主键id|20250402|XXX'primary key,user_id      bigint                                not null comment 'userId|20250402|XXX',order_no     varchar(64) default ''                not null comment '订单号|20250402|XXX',status       varchar(64) default ''                not null comment '分账状态:init 初始化,process处理中, success成功 fail失败',remark       varchar(256)                          null comment '备注|20250402|XXX',delete_flag  int         default 1                 null comment '删除标记(1:正常 0:删除)|20250402|XXX',revision     bigint      default 1                 not null comment '乐观锁|20250402|XXX',created_by   varchar(256)                          null comment '创建人|20250402|XXX',created_time datetime    default CURRENT_TIMESTAMP not null comment '创建时间|20250104|XXX',updated_by   varchar(45)                           null comment '更新人|20250104|XXX',updated_time datetime    default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间|20250104|XXX'
)comment '订单分账表|20250402|XXX';create index idx_create_timeon db_paycenter.t_pay_order_divide (created_time);create index idx_updated_timeon db_paycenter.t_pay_order_divide (updated_time);

乐观锁这个字段,很好奇。

    revision     bigint      default 1                 not null comment '乐观锁|20250402|XXX',
问一下kimi试试,

2、问题提问

revision     bigint      default 1                 not null comment '乐观锁|20250402|XXX',

数据库字段如上定义,乐观锁一般怎么现实

3、问题解答

乐观锁(Optimistic Locking)是一种在数据库操作中常用的并发控制机制,它假设在大多数情况下,数据在读取和修改期间不会发生冲突。乐观锁通过版本号(Version Number)或时间戳(Timestamp)来实现,每次更新数据时,都会检查版本号或时间戳是否发生变化,从而避免并发冲突。

乐观锁的实现方式

在你的数据库字段定义中,revision 字段被用作乐观锁的版本号字段。以下是乐观锁的典型实现步骤:

1. 数据库字段设计

你的字段定义已经很好地体现了乐观锁的设计:

revision BIGINT DEFAULT 1 NOT NULL COMMENT '乐观锁|20250402|XXX',
    • revision 字段用于存储版本号,默认值为 1

    • 每次更新记录时,revision 字段的值会递增。

    2. 读取数据

    当应用程序读取数据时,会同时获取 revision 字段的值。例如:

    SELECT id, name, revision FROM your_table WHERE id = 1;

    假设查询结果为:

    id | name | revision
    1  | Test | 1

    3. 修改数据

    在更新数据时,应用程序会检查 revision 字段的值是否发生变化。如果发生变化,说明其他事务已经修改了这条记录,当前事务需要重新读取数据或放弃更新。

    更新操作的 SQL 语句如下:

    UPDATE your_table
    SET name = 'New Name', revision = revision + 1
    WHERE id = 1 AND revision = 1;
    • revision = revision + 1:将版本号递增。

    • WHERE id = 1 AND revision = 1:确保只有当版本号未发生变化时,才允许更新。

    4. 检查更新结果

    执行更新操作后,数据库会返回受影响的行数。如果受影响的行数为 0,说明更新失败(即 revision 字段的值已经发生变化,其他事务已经修改了这条记录)。

    在应用程序中,可以检查更新结果:

    int rowsAffected = jdbcTemplate.update("UPDATE your_table SET name = ?, revision = revision + 1 WHERE id = ? AND revision = ?","New Name", 1, 1
    );if (rowsAffected == 0) {throw new OptimisticLockException("数据已被其他事务修改");
    }

    乐观锁的优点和缺点

    优点
    1. 性能较好:在大多数情况下,数据不会发生冲突,因此不需要加锁,减少了锁的开销。

    2. 适合高并发场景:适用于读多写少的场景,能够有效避免锁竞争。

    缺点
    1. 冲突处理复杂:当发生冲突时,需要重新读取数据或放弃更新,增加了复杂性。

    2. 不适合写多场景:如果数据频繁更新,冲突的可能性会增加,性能优势可能会减弱。

    乐观锁与悲观锁的对比

    • 悲观锁(Pessimistic Locking):假设冲突是常态,通过加锁来避免冲突。适合写多场景,但性能开销较大。

    • 乐观锁(Optimistic Locking):假设冲突是少数情况,通过版本号或时间戳来检测冲突。适合读多写少的场景,性能较好。

    总结

    乐观锁通过版本号字段(如 revision)来实现,每次更新数据时,都会检查版本号是否发生变化。如果版本号发生变化,说明其他事务已经修改了这条记录,当前事务需要重新读取数据或放弃更新。乐观锁适用于读多写少的场景,能够有效减少锁的开销,提高性能。

    http://www.xdnf.cn/news/1949.html

    相关文章:

  • AiFlutter 低代码平台介绍
  • hadoop-3.3.5.tar.gz 镜像
  • Hi3516CV608 超高清智慧视觉 SoC 芯片 可提供开发资料
  • Python 快速获取Excel工作表名称
  • Easysearch 基础运维扫盲指南:从 HTTP 到 HTTPS、认证与安全访问全解析
  • 侧扫声呐概述
  • Ollama 常见命令速览:本地大模型管理指南
  • arcpy列表函数的应用(2)
  • 数据作为新生产要素,如何实现价值变现?
  • 向量数据库实践:存储和检索向量数据
  • Python实验三
  • 论文学习:《聚类矩阵正则化指导的层次图池化》
  • Java多线程
  • 2.5 桥梁桥面系及附属结构施工
  • kafka课后总结
  • Spring @Transactional 自调用问题深度解析
  • 【Unity 与c++通信】Unity与c++通信注意事项,参数传递
  • websheet之 自定义函数
  • 成都种业博览会预登记火热进行中,6月8日-9日成都世纪城新国际会展中心与您不见不散!
  • [密码学实战]商用密码产品密钥体系架构:从服务器密码机到动态口令系统
  • vue前端SSE工具库|EventSource 替代方案推荐|PUSDN平行宇宙软件开发者网
  • 如何申请游戏支付平台通道接口?
  • PyTorch生成式人工智能实战(3)——分类任务详解
  • 施磊老师基于muduo网络库的集群聊天服务器(七)
  • 容器的网络类型
  • 视频噪点多,如何去除画面噪点?
  • 【基于Qt的QQMusic项目演示第一章】从界面交互到核心功能实现
  • 常见移动机器人底盘模型对比(附图)
  • Codeforces Round 1020 (Div. 3) A-D
  • 用diffusers库从单文件safetensor加载sdxl模型(离线)