欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 养生 > 支付场景下,乐观锁的实现(简洁版)

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

2025/4/26 5:23:19 来源:https://blog.csdn.net/u013803955/article/details/147520114  浏览:    关键词:支付场景下,乐观锁的实现(简洁版)

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

    版权声明:

    本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

    我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

    热搜词