V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
Vibe 了一个 _代码质量可能很高_ 脚手架
一个完全由 Vibe 创作的脚手架,Gemini 给出的评分是 9.5/10
Promoted by Visoar
ljzxloaf
V2EX  ›  程序员

你们会用乐观锁来防止并发冲突吗

  •  
  •   ljzxloaf · 2024-07-17 16:17:01 +08:00 · 3797 次点击
    这是一个创建于 374 天前的主题,其中的信息可能已经有所发展或是发生改变。
    并发冲突似乎是个大家都在谈,但是很少有人真的去当回事的东西。

    典型的如 innodb 的 mvcc 就是用乐观锁的方式去处理并发冲突,你可以通过设置不同的隔离级别让 innodb 在检测到并发修改的时候选择不同的处理方式。

    在业务开发中,当用户并发修改某条数据的时候,我们也可以通过类似的方式去防止或协调冲突。
    那么问题来了,在实际工作你们真的去这么做了吗?如果没有这样实践的话是啥原因呢?就我个人的经验而言,好像很少有人真的这么干。
    28 条回复    2024-07-21 17:25:40 +08:00
    wangxin3
        1
    wangxin3  
       2024-07-17 16:23:10 +08:00
    个人愚见:
    并发修改在 i++时会有问题,所以要考虑并发;
    日常开发大多都是 i=?的问题吧,不存在冲突,后者覆盖 i 就行。
    CEBBCAT
        2
    CEBBCAT  
       2024-07-17 16:26:32 +08:00
    有的不 ACID 要亏钱,也有的只是制造了一些小小的业务漏洞。看时间充裕与否吧。如果要我当下给出回答,我的解是:

    从整体方案上减小冲突可能性,从扩展性上支持未来升级,从数据安全角度可回溯
    emSaVya
        3
    emSaVya  
       2024-07-17 16:27:00 +08:00
    写业务的人不会牺牲自己服务的吞吐量 去考虑下游数据环节的问题。下游的问题交给下游 我不会在自己服务的主流程上加任何锁。
    chippai
        4
    chippai  
       2024-07-17 16:30:35 +08:00
    从实际工作来讲还是很常用的,比如版本防并发修改、库存防超发等
    samtofor
        5
    samtofor  
       2024-07-17 16:32:13 +08:00
    一般在开发的时候不怎么用锁,需要用锁的时候也都是悲观锁,乐观锁基本没用过
    ninjashixuan
        6
    ninjashixuan  
       2024-07-17 16:33:00 +08:00
    和钱相关的业务才会开始就考虑,其他的基本不会。
    samtofor
        7
    samtofor  
       2024-07-17 16:33:29 +08:00
    @samtofor 防喷,因为我接触的业务规模都不大,那么点用户量是不需要考虑乐观锁这种事情的
    cheng6563
        8
    cheng6563  
       2024-07-17 16:33:36 +08:00
    加啊,开发框架集成,一个配置搞定,无形中避免了并发冲突,为何不加
    byehair
        9
    byehair  
       2024-07-17 16:35:11 +08:00   ❤️ 1
    我的实际工作中,只要可能存在并发冲突的时候,在数据库层面我几乎都会使用乐观锁处理,但几乎很少使用悲观锁。
    但是,但是,但是,
    在数据库操作之前,我一般会使用其他手段,前置处理并发,比如使用 redis 做分布式锁、比如使用消息队列消费再写数据库等。

    数据库层面使用乐观所或者悲观锁是我的最后一道防线,前置的分布式、内存锁、队列等都是为了从宏观上更高效的防止并发冲突。

    一个不恰当的例子:
    宇宙飞船是密封的,但是更保险的是穿上宇航服,因为有可能宇宙飞船被撞出一个洞,也可能宇航员要出仓执行任务,虽然有各种外层防御措施,但宇航服是最后一道防线。
    NoobNoob030
        10
    NoobNoob030  
       2024-07-17 16:36:49 +08:00
    加,遇到有并发的要求的需求,顺手加一个很快
    elonlee
        11
    elonlee  
       2024-07-17 16:41:11 +08:00
    如果是分布式程序用 redis 同步锁,单体程序用可重入锁实现,数据库锁太重了,影响写入性能.
    samtofor
        12
    samtofor  
       2024-07-17 16:44:01 +08:00
    @helloluckydamon 赞同,大部分开发时候我都是避免使用数据库锁的,处理金钱相关的基本都是用 mq 的分区顺序来处理的,直接避免使用锁,实际用悲观锁的场景其实是在管理端,是用来防止几个人同时操作才写的,这种场景下悲观锁对于我的来说成本更低
    Aruforce
        13
    Aruforce  
       2024-07-17 16:56:35 +08:00 via Android
    那么乐观锁前提下 是否需要重试以及 怎么对数据库的隔离级别有啥要求?
    ljzxloaf
        14
    ljzxloaf  
    OP
       2024-07-17 16:58:00 +08:00
    @cheng6563 #8 啥框架?
    diagnostics
        15
    diagnostics  
       2024-07-17 16:58:07 +08:00
    @samtofor #5 OP 说的乐观锁是应该是依赖数据库避免并发冲突的
    ljzxloaf
        16
    ljzxloaf  
    OP
       2024-07-17 16:59:10 +08:00
    @samtofor #7 同一用户开两个客户端( app 、pc )就能触发了
    zjsxwc
        17
    zjsxwc  
       2024-07-17 17:05:28 +08:00
    多人操作、有版本差异需求的都要
    watzds
        18
    watzds  
       2024-07-17 18:12:32 +08:00
    有些严格的会控制的,保证页面修改是基于最新内容,防止 A 把页面改了,B 基于 A 修改前的再修改,会把 A 的修改覆盖掉
    lovelylain
        19
    lovelylain  
       2024-07-17 18:36:05 +08:00 via Android
    大部分都会,对于楼上说的保证页面基于最新内容防止覆盖,还会考虑实际成功但前端超时等原因误判后重试。
    csys
        20
    csys  
       2024-07-17 18:40:50 +08:00 via Android
    乐观锁是个很尴尬的东西,高并发高资源竞争下会放大压力
    我觉得要么直接在上层用分布式锁,要么优化成无锁的设计
    mshadow
        21
    mshadow  
       2024-07-17 22:39:32 +08:00 via Android
    18 楼说的是主要场景。其他高并发场景一般用分布式锁。
    Huelse
        22
    Huelse  
       2024-07-17 22:43:55 +08:00
    postgresql 中我们就用乐观锁,因为 mvcc 的关系
    hekkowoerld
        23
    hekkowoerld  
       2024-07-17 23:19:48 +08:00
    @helloluckydamon 大佬有对比过吗?性能大概有多大的提升?其实说白了乐观锁和悲观锁主要就是性能差异。
    ZeawinL
        24
    ZeawinL  
       2024-07-17 23:59:50 +08:00 via iPhone
    看数据重要程度
    laminux29
        25
    laminux29  
       2024-07-18 03:24:09 +08:00
    1.锁性能的关键在于 CPU 、主板、内存 的主频下限,这是个木桶效应问题。

    2.业务量小的系统,不需要考虑这个问题,直接用数据库的序列化事务,来处理这类数据。

    3.业务量大的系统,不靠数据库来处理,而是在系统的设计阶段,就会根据第一条的机器性能,把业务进行拆分,拆分到不同的业务集群里。举个例子,用户注册的用户名唯一性查询,会按照首字母 + 数据量,进行物理数据库服务器拆分,并且这类物理数据库服务器,会选用高频设备:高频 CPU + 高频主板 + 高频内存。
    RightHand
        26
    RightHand  
       2024-07-18 07:52:34 +08:00 via Android
    哎,干了这么多年还没用过乐观锁。另外乐观锁这词又是哪里来的?
    duhbbx1119
        27
    duhbbx1119  
       2024-07-18 21:02:13 +08:00
    之前用的比较多的是版本控制,数据库中加个字段记录版本,update 的时候比较下
    byehair
        28
    byehair  
       2024-07-21 17:25:40 +08:00   ❤️ 1
    @hekkowoerld 并没有实际对比过,没有实际对比主要是两点原因:
    1. 懒
    2. 乐观锁和悲观锁的性能差异在不同条件下是不一样的,要看自旋的成本和调度的成本

    假设你获取到锁的线程执行任务周期长,或者锁竞争很激烈,那么也许悲观锁性能更高
    反之亦然
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1105 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 23:38 · PVG 07:38 · LAX 16:38 · JFK 19:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.