V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
ljzxloaf
V2EX  ›  程序员

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

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

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

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

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

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

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

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

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

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