讨论下表单多次点击的问题

场景: 房间开游戏

问题

点击`开始游戏`,先判断房间是否有正在进行的游戏, 没有则新增一条游戏记录
假如瞬间无穷短的时间内多次点击了`开始游戏`, 那么多次 select id 都查不到记录,就会新增多条记录,就会在结束游戏的时候会出现多个没结束的游戏

解决思路:

那么要怎么才能只有一条游戏记录呢? 我这里想到的就两种途径, 一种是 `select` 的时候进行查重,一种是 insert 的时候进行锁全表并且查重。
  • insert时锁表并且进行查重
    这个重复之后的处理逻辑就是对所有事务进行回滚,并且通知客户端,点击重复了。
  • select时怎么防呢
    增加表锁吗? 貌似特别耗性能,而且这操作我也不会
    我能想到的就是使用 redis 记录当前事件, 查询redis是否存在事件,如果存在通知客户端点击重复了,如果没有则新增一个记录,然后 redis 会不会也出现无穷短的时间内查询出不存在的结果呢?还有没有别的更好的办法呢
        //查重
        $key = "room_" . $liveuid . "_BigDial";
        $GameExsit = DI()->redis->get($key);
        if($GameExsit)
        {
            $rs['code'] = 1001;
            $rs['msg'] = '游戏正在开启, 请勿多次点击';
            return $rs; 
        }
        //防止游戏开启失败无法清除键
        DI()->redis->setEx($key,"begin",2);
        //游戏开启成功后清除
        if(Game()->begin) DI()->redis->del($key);
        //后续逻辑
本作品采用《CC 协议》,转载必须注明作者和本文链接
reading
白小二
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 3

1、使用redis锁 博客:分布式锁的实现

2、在表单生成的时候填充一个随机token,将这个token存到session中,当提交后判断token是否一致,一致则说明是第一次提交,此时删除这个token,否则的话就说明已经提交过了

1年前 评论
白小二 (楼主) 11个月前
  1. 前端优化, 点击后按钮标记禁用,x 秒后自动解除禁用状态(不管是否提交成功),添加 loadding 等字样
  • 提交成功重置表单或跳转其他页面,
  • 提交失败提示原因让用户选择处理
  1. 使用 csrf 或其他, 确保不重复提交
1年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!