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

数据同步问题

  •  
  •   theknotyouknow · 2020-12-17 22:45:45 +08:00 via iPad · 1469 次点击
    这是一个创建于 1225 天前的主题,其中的信息可能已经有所发展或是发生改变。
    现在有一个电商网站,需要用户点击登陆才能购买,对于新用户需要注册,注册需要调用底层的 passport 服务。现在新用户从客户端和浏览器同时发起注册,调用这个 passport 服务,为这个新用户注册账号,有两个问题;首先,passport 如何保证对于同一个用户只有一个请求注册的请求能成功,前提条件是假设注册新用户写 db 的时间在 100ms 左右,而这新俩同时发起的注册请求在 100ms 以内。第二个问题是,如果 passport 保证不了,调用方如何保证这种场景下只有一个请求能到 passport,或者在 passport 现状下,调用方如何最优处理呢
    10 条回复    2020-12-19 00:33:59 +08:00
    echowuhao
        1
    echowuhao  
       2020-12-17 23:44:48 +08:00
    数据库表 id unique constraint,同时插入也只能一个成功。
    laminux29
        2
    laminux29  
       2020-12-18 00:30:22 +08:00
    第一个问题的原理是,注册时,通过用户名与手机号,进行唯一性限制。如果客户端先行注册了,数据库那边就存在了该用户名与手机号,浏览器端注册时,发现用户名与手机号已经存在,然后反馈:用户名或手机号已经被注册。

    第二个问题的原理是,数据库可以把该操作按业务或架构需求,设置为某种级别的事务性,比如串行,来保证该操作的原子性。就算两个请求是同时达到数据库服务器,因事务的原子性,两个请求任然会被强行分为一前一后,按顺序进行。

    第三个问题,passport 服务必须要保证注册业务的事务性。保证不了就换程序员或 DBA 。
    theknotyouknow
        3
    theknotyouknow  
    OP
       2020-12-18 08:10:19 +08:00 via iPad
    前提条件是假设注册新用户写 db 的时间在 100ms 左右,而这新俩同时发起的注册请求在 100ms 以内。数据库保证不了吧,还没插入成功
    gosansam
        4
    gosansam  
       2020-12-18 09:54:50 +08:00
    @theknotyouknow 用户唯一标识做 key 加锁可行吗
    no1xsyzy
        5
    no1xsyzy  
       2020-12-18 10:23:35 +08:00
    注册不是热点直接串行就行了
    如果注册是热点,比如你期望的每日用户增长数大于 28.8 万,或者说每小时用户增长数大于 3.6 万,那你大概不用考虑先验唯一性限制,写完了确认下唯一性,不唯一把后插入的那条去掉。

    还有一种,就是(比如你用手机号)下发或者上发验证码,并且不同终端的验证码不同,请求新验证码会无效化之前的验证码。
    bjhc
        6
    bjhc  
       2020-12-18 11:10:52 +08:00
    只要保证调用操作的原子性就可以了。有多种实现方式。
    第一,数据库层面,主键或唯一索引。
    第二,队列。将注册调用串行化。redis 等各种消息队列即可满足。
    theknotyouknow
        7
    theknotyouknow  
    OP
       2020-12-18 13:04:53 +08:00 via iPad
    @gosansam 可行,调用方我能想到只能这样做了,并发的控制粒度是 redis 加锁的时间
    theknotyouknow
        8
    theknotyouknow  
    OP
       2020-12-18 13:09:41 +08:00 via iPad
    @bmwyhc 第一种方案,是不是会导致锁表
    theknotyouknow
        9
    theknotyouknow  
    OP
       2020-12-18 13:11:09 +08:00 via iPad
    @no1xsyzy 失败后,发起重试,不一定是用户的重试呢
    no1xsyzy
        10
    no1xsyzy  
       2020-12-19 00:33:59 +08:00
    @theknotyouknow 没看懂你说啥……
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2797 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 12:16 · PVG 20:16 · LAX 05:16 · JFK 08:16
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.