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

请教大家一个后端菜单功能的实现问题

  •  
  •   dumbbell5kg · 2022-06-23 18:25:22 +08:00 · 1919 次点击
    这是一个创建于 644 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我现在有一个菜单 menu

    有这么一种并发的操作情况:

    • 用户 A 往 menu 中增加内容 content ,同时用户 B 在删除 menu ,如果 B 先成功,那么 A 新增的 content 就变成了孤儿。

    我目前想到的解决办法有两种:

    • 使用 redission 分布式锁锁住 menu ,但是这样同一个 menu 下的操作会变慢,另外:多人同时往菜单下增加内容的这种无冲突操作也受到影响了
    • 使用乐观锁机制,往菜单表中加一个 version 字段,AB 两者每次操作都更新菜单的 version:update version=2 where version=1 ,但是这样其中一个人的操作会报错“数据已更新,请刷新页面”,刷新页面会让前端拿到新的 version ,但是对用户不友好

    所以想请教大家一般是怎么处理这种菜单的并发问题呢?

    10 条回复    2022-06-24 21:37:35 +08:00
    timethinker
        1
    timethinker  
       2022-06-23 18:47:39 +08:00
    没明白你说的对用户不友好是啥意思,往一个已经删除的关联数据增加新的数据,按理说应该失败并告知原因,例如不存在 menu ,除此之外还能怎么做呢?可以吞掉这个错误,就当请求没发生,或者正常插入脏数据?

    数据已被删除是一个事实,优化的方案也可以当有用户编辑 menu 的时候不允许删除,这取决于想要的逻辑是什么。

    回到正题,解决这个并发问题最简单的方法就是使用乐观锁,或者直接使用独占锁( SELECT ... FOR UPDATE )。如果是独占锁,当你在进行操作的时候(新增 content ),别人是没办法查询或者修改这个 menu 的。当完成操作,另一个试图删除 menu 的时候,走正常的删除逻辑。
    TWorldIsNButThis
        2
    TWorldIsNButThis  
       2022-06-23 19:13:18 +08:00 via iPhone
    我用的是 2
    配合 retry
    Saxton
        3
    Saxton  
       2022-06-23 20:17:35 +08:00 via iPhone
    数据库的事物+锁已经足够了
    renmu123
        4
    renmu123  
       2022-06-23 23:54:30 +08:00 via Android
    什么场景会有两个用户同时编辑一个菜单,就算有一般也是 b 端的吧。
    又不是不能用.jpg 两人自己沟通去
    hidemyself
        5
    hidemyself  
       2022-06-24 08:07:40 +08:00
    我也是用 2
    sujin190
        6
    sujin190  
       2022-06-24 09:26:49 +08:00
    其实是不是想太多了,且不说同一个 menu 能被几个人操作啊,就算真的多现实情况下同时操作又有多大概率,直接加锁顶多慢几百毫秒而已,这真的不算个啥,还是别过度设计啊,如果并发冲突直接加锁超过 20%慢超过 5 秒以上,我觉得还有价值用 2 乐观锁加自动重试就行,否则除了增加不稳定因素和复杂度真的毫无优化的必要
    night98
        7
    night98  
       2022-06-24 10:19:45 +08:00
    直接加锁,菜单操作是个低频率的操作,冲突概率极低
    gitdoit
        8
    gitdoit  
       2022-06-24 16:41:45 +08:00
    不要过度设计,编辑菜单是低频操作,直接乐观锁就行了。就算发生你说的那种冲突,你觉得你在代码里能做什么呢
    cp19890714
        9
    cp19890714  
       2022-06-24 20:41:04 +08:00 via Android
    基本就是这两种方案。根据功能的具体使用情况,来选择用哪个方案。区别的关键在于,用户对菜单删除的操作,和菜单下添加内容的操作,哪个更频繁。如果删除操作更频繁,就使用悲观锁,如果添加内容更频繁,就使用乐观锁。
    fov6363
        10
    fov6363  
       2022-06-24 21:37:35 +08:00
    类型读写锁的思路:增加拿锁 1 ,删除拿锁 2 ,锁 1 与锁 2 互斥,锁 1 可同时存在多个,锁 2 只允许存在一个
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5820 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 06:20 · PVG 14:20 · LAX 23:20 · JFK 02:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.