Neil66
V2EX  ›  科技

新增一条数据到数据库,如何可以避免重复(前后端)

  •  
  •   Neil66 · Jun 24, 2022 · 3262 views
    This topic created in 1600 days ago, the information mentioned may be changed or developed.

    软件开发,create 操作,新增一行业务数据到数据库中,用户如果重复点击提交按钮就会导致数据库重复,各位大佬们有哪些解决方案呢?前后端、数据库、架构设计之类方案都可以分享一下

    18 replies  •  2022-06-25 08:41:07 +08:00
    qping
    qping
    Jun 24, 2022
    1
    百度:防止表单重复提交
    seanzxx
    seanzxx
    Jun 24, 2022
    2
    数据库不是有主键和唯一键吗?
    rabbbit
    rabbbit
    Jun 24, 2022
    3
    单独有个校验接口,用户输入时前端(节流 300s 一次)调这个接口校验值是否重复,重复则提醒用户。
    后端提交时再校验一次。
    aitaii
    aitaii
    Jun 24, 2022
    4
    数据库兜底,前端,网关可以做校验,幂等操作
    66beta
    66beta
    Jun 24, 2022
    5
    各做各的,后端是最后的防线
    aitaii
    aitaii
    Jun 24, 2022
    6

    流程说明:

    前端服务进入页面从服务端获取 token ,服务端生成 token 放入 redis 返回。
    前端调用业务接口请求时,把 token 携带过去,一般放在请求头部。
    服务端删除 redis 中的 token 并判断是否成功,若成功继续执行业务。
    若删除失败表示是重复操作,直接返回重复标记给 client 。
    rabbbit
    rabbbit
    Jun 24, 2022
    7
    问个问题,假如两个人分别在两地修改同一个条数据,后端分布式是如何解决这种数据可能不一致的问题的?
    是只有一个数据库吗?还是多个数据库只有一个写,其他的读?
    wolfie
    wolfie
    Jun 24, 2022
    8
    最简单前端 disable 控件。
    后端弄就麻烦了。
    hidemyself
    hidemyself
    Jun 24, 2022
    9
    @rabbbit 版本号
    sanmaozhao
    sanmaozhao
    Jun 24, 2022
    10
    如果后端本身是允许两条完全一样的数据存在的话,比如用户正常操作两次,只是录入的数据相同
    那这个事情就和后端没有关系了
    前端提交按钮在结果没返回前进入 busy 状态就行
    Chemist
    Chemist
    Jun 24, 2022 via iPhone❤️1
    11
    本质上还是怎么区分两条一模一样的数据是
    “确实想造两条一样的数据”这个需求来的,还是“不小心重复请求”这个异常

    一般创建接口就是创建。

    为了用户不误操作就前端坐处理,创建成功后做好提示,展示成功页面。

    后段不放心就做请求限制,重复请求拦截的时间限制不应该大于用户正常填写完表单的时间。
    BugCry
    BugCry
    Jun 24, 2022 via Android
    12
    关键词:幂等性、nonce 、timestamp
    duanxianze
    duanxianze
    Jun 24, 2022
    13
    本质上还是先看你的需求,如果只是发微博这种,其实靠前端限制就行,后端设置个请求频次限制,如果是银行交易,那就复杂了,没搞过,不多说了
    aecra1
    aecra1
    Jun 24, 2022 via Android
    14
    @rabbbit CAP 定理,一致性 /可用性 /分区容错性不可同时满足,根据业务取舍
    cvbnt
    cvbnt
    Jun 24, 2022 via Android
    15
    redis 做幂等性提交,大致是 6 楼的过程,在删除的过程中为了保证事务,推荐用 lua 脚本删除,比如
    if redis.call("get",KEYS[1])==ARGV[1] then
    return redis.call("del",KEYS[1])
    else
    return 0
    end
    如果 redis 环境是集群,可能需要对键值做额外设置
    nigulasida
    nigulasida
    Jun 24, 2022
    16
    pg 可以 insert-up
    EscYezi
    EscYezi
    Jun 25, 2022 via iPhone
    17
    前端点击后加 loading ,后端每次请求开始加个单个用户级别 redis 锁,请求结束释放(或者结束一秒后过期)。一次请求期间如果同一个用户再次发起请求直接返回操作频繁,基本上可以避免重复提交。也可以做成用户&接口粒度的。
    sunnysab
    sunnysab
    Jun 25, 2022
    18
    @nigulasida insert-up 是 insert update 吗?
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1397 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 51ms · UTC 16:52 · PVG 00:52 · LAX 08:52 · JFK 11:52
    ♥ Do have faith in what you're doing.