关于在多台服务器对同一张表进行查询的过程中中遇到的错误 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MySQL 5.5 Community Server
MySQL 5.6 Community Server
Percona Configuration Wizard
XtraBackup 搭建主从复制
Great Sites on MySQL
Percona
MySQL Performance Blog
Severalnines
推荐管理工具
Sequel Pro
phpMyAdmin
推荐书目
MySQL Cookbook
MySQL 相关项目
MariaDB
Drizzle
参考文档
http://mysql-python.sourceforge.net/MySQLdb.html
lsrnb
V2EX    MySQL

关于在多台服务器对同一张表进行查询的过程中中遇到的错误

  •  
  •   lsrnb 2023 年 1 月 18 日 2587 次点击
    这是一个创建于 1119 天前的主题,其中的信息可能已经有所发展或是发生改变。

    pS3fiZt.png 我遇到了这样的错误,我尝试 baidu/google,但是没有解决方法.
    V 友们,我应该如何解决他?

    9 条回复    2023-01-19 14:48:56 +08:00
    suke119
        1
    suke119  
       2023 年 1 月 18 日 via iPhone
    。。。。常见的乐观锁不就搞定了
    seers
        2
    seers  
       2023 年 1 月 18 日
    分布式锁
    yaodao
        3
    yaodao  
       2023 年 1 月 18 日 via iPhone
    如果并发量不大,可以用简单的 redis 分布式锁或者数据库的乐观锁
    lsrnb
        4
    lsrnb  
    OP
       2023 年 1 月 18 日
    @suke119 乐观锁是修改 version 吗?第一次修改是 0,第二次修改是 1 这样吗?
    update `user` set stau = 100001, version = 1 where stau = 100000 and version = 0;
    这样的我测试了不行,因为第一台服务器修改的结果还没传到数据库 version 还是=0,第二台服务器执行还是返回跟第一台相同的结果
    suke119
        5
    suke119  
       2023 年 1 月 18 日 via iPhone
    @lsrnb 所以问题出在你的理解上啊,任何客户端都可以修改,你无法控制客户端的行为,你能做的只有保证谁入库谁为主,如果第一个因为网络有问题没有修改完成,但是此时第二个用户可以任何操作的,他有这个权利,如果他的行为 db 提交,不管是不是在上一个用户之前都是正确的,完成后第一个用户提交自然就因为版本不对失败
    n0099
        6
    n0099  
       2023 年 1 月 19 日
    乐观并发控制是要求每个客户端的后续读写都得依赖于此前查询所获得的的`ROW_VERSION`
    比如事务 1`SELECT yi, ver FROM t`获得`(a,0)`
    那么事务 1 后续的所有对该行的读写( SELECT/UPDATE )都得依赖于`ver=0`这个此前获得的事实
    也就是对于读:事务 1 期望重新`SELECT yi, ver FROM t`获得的还是`(a,0)`,这叫做`REPEATABLE READ`(避免了幻读`phantom read`),注意 mysql 默认的事务隔离级别就是`REPEATABLE READ`所以默认是已经保证了在同一事务内不断重新执行`SELECT yi, ver FROM t`返回的永远都是`(a,0)`
    对于写:事务 1 期望`UPDATE t SET 某个其他字段 = 某值 WHERE yi = a AND ver = 0`所返回的`affected rows`是 1 行,而如果不是 1 行而是 0 行就意味着表 t 中已经不存在符合约束`WHERE yi = a AND ver = 0`的行,也就是说行`yi=a`已经被其他事务修改了

    建议参考以某企业级 orm EFCore 为背景的 MSDN 微软谜语: https://learn.microsoft.com/en-us/ef/core/saving/concurrency
    以及我之前对于类似的场景(但是是 INSERT-only 而不是 UPDATE )使用了数据库层提供的悲观并发控制,毕竟在 SQL 末尾加`FOR UPDATE`可比在 mysql 里用 TRIGGER 模拟单调递增的自增 sql server 的 ROW_VERSION 类型然后在程序业务逻辑里写乐观控制所带来的一大堆 if 简单多了: t/908047
    dog82
        7
    dog82  
       2023 年 1 月 19 日
    认识到这个问题所在并能想办法解决,就晋级成中级码农了
    Freeego
        8
    Freeego  
       2023 年 1 月 19 日
    这个需求有点奇怪,意思是前端只处理一次数据?这样的话在后端加个分布式锁,在查询命令的时候加锁,字段 yi 修改到 1 之后再解锁。
    matepi
        9
    matepi  
       2023 年 1 月 19 日
    除了前面各位讲到的锁方式

    其实在非强联机场景下可以用任务队列的方式,也会有很多的好处
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1128 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 17:53 PVG 01:53 LAX 09:53 JFK 12:53
    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