如何原子性的重排某个队列 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
ayanamist
V2EX    问与答

如何原子性的重排某个队列

  •  
      ayanamist 2011-06-07 20:29:02 +08:00 4673 次点击
    这是一个创建于 5279 天前的主题,其中的信息可能已经有所发展或是发生改变。
    某需求,当前存在一个有序队列,要求可以原子性的增加、删除、重排列表中的元素。并且队列的内容是通过Web来管理和交互的。
    有没有什么很好的解决方案?目前存储和算法都没定,只是打算用Python实现。
    用锁和优先级的话,由于多用户访问时,可能出现以下情况导致原子性丧失:
    1、A用户打开页面
    2、B用户打开页面
    3、A用户添加了一个元素,并提交(此时这个修改并没有反馈到B用户那里去)
    4、B用户重排了列表。此时会有冲突,用优先级来实现的话,必然可能出现重排后的原始列表中的某项和后添加的那个元素优先级冲突,造成逻辑丧失。
    不知道除了优先级和锁的方法,还有什么比较好的实现?
    15 条回复    1970-01-01 08:00:00 +08:00
    aligo
        1
    aligo  
       2011-06-07 20:37:20 +08:00
    (此时这个修改并没有反馈到B用户那里去)

    你自己已经知道问题所在了,如果是在线协同作业的话,利用各种polling方式更新客户端就好了
    ssword
        2
    ssword  
       2011-06-07 20:39:04 +08:00
    "原子性"是指时间周期内不可分割的操作,跟单纯保证并发的正确性不是一回事。看楼主的描述似乎更像是强调实时更新,而不是强调并发。
    不大懂“优先级和锁”是怎样的方法,不过仅仅要求数据一致性的话,一般的DBMS都有事务功能可以用。
    ayanamist
        3
    ayanamist  
    OP
       2011-06-07 20:41:29 +08:00
    @aligo poll很浪费资源啊……毕竟这种数据碰撞的情况比较少……
    ayanamist
        4
    ayanamist  
    OP
       2011-06-07 20:42:09 +08:00
    @ssword 不需要实时更新。我想描述的是解决数据碰撞的问题。除了用poll,还有什么办法能解决我描述的那个问题吗?
    ssword
        5
    ssword  
       2011-06-07 20:49:14 +08:00
    @ayanamist 大致明白了,这问题跟原子性无关。
    可以这样:每个列表对应一个表单,里面带一个版本号。每次新提交都让版本号+1,如果一个新提交的版本号不是最新,简单地回复给用户一个错误就行。
    ayanamist
        6
    ayanamist  
    OP
       2011-06-07 20:59:33 +08:00
    @ssword 你这太粗暴了……我需要的是平和处理……我刚想到vcs一定会遇到这个问题,两个人co以后,做了不同的修改,同时commit,会发生什么?
    ssword
        7
    ssword  
       2011-06-07 21:04:53 +08:00
    @ayanamist 等解决好这个和平问题,git/svn即可退出历史舞台
    reus
        8
    reus  
       2011-06-07 21:22:00 +08:00
    貌似这种情况是先要update一下再commit的,如果可以自动合并就合并,commit成功。不能的话,要你自己解决冲突。
    所以可以在提交之前更新一下状态并提示用户。
    其实我好奇这是啥功能呢?
    ayanamist
        9
    ayanamist  
    OP
       2011-06-07 21:51:38 +08:00
    @reus @ssword 研究了一下git,确实需要人工干预。
    想了想,也许只有用户每次操作(包括重排时的每次改变单个元素的顺序)的时候ajax提交,然后服务器用版本号判断,如果版本号不匹配,就放弃此次操作,并返回最新版本的数据比较妥当
    reus
        10
    reus  
       2011-06-07 22:28:14 +08:00
    我还是好奇这是个啥东西,具体说说吧?或者有其他的解决方法也说不定的啊,不一定要用同步的方式。比如可以用branch+merge的模型
    lepture
        11
    lepture  
       2011-06-08 00:21:07 +08:00
    一定要同时操作的么?
    如果A进入了该资源的修改状态,则其它人不可修改,这样子不行么?
    dreampuf
        12
    dreampuf  
       2011-06-08 02:52:18 +08:00 via Android
    时间戳
    nleven
        13
    nleven  
       2011-06-08 03:12:12 +08:00
    把重排放到服务端去做就好了吧。
    B不要把新列表的具体内容传给服务器,只是告诉它去重排。服务端显然总是有最新的列表,让它去重排的话就根本不会冲突了。
    aligo
        14
    aligo  
       2011-06-09 08:09:20 +08:00
    @ayanamist 其实是各种polling,例如long-polling
    或者最简单的一个办法如你上面说的,像各种版本管理系统,给每次的变更提供一个hash,A用户添加了东西之后,就改变了那个hash
    而B用户客户端的排列的还是原来的hash,B用户在提交的时候就会遇到hash冲突,这时候再更新B眼中的内容,让他解决冲突然后提交好了
    aligo
        15
    aligo  
       2011-06-09 08:11:45 +08:00
    我做过的大家也都做过的类似的应用场景
    就是在注册一个用户的时候,输入用户名会检查一遍有没有重复的用户名
    最后用户确认提交的时候再一次的检测同时添加数据
    darasion
        16
    darasion  
       2011-06-09 08:16:53 +08:00
    恰好我也正在做这种事情。发现式设计起来很麻烦,现在还在头疼中。

    还涉及到工作流什么什么的,更麻烦了。两边都要有解决冲突的机制。

    郁闷啊。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3987 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 04:12 PVG 12:12 LAX 20:12 JFK 23:12
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86