讨论下表单多次点击的问题
场景: 房间开游戏
问题
点击`开始游戏`,先判断房间是否有正在进行的游戏, 没有则新增一条游戏记录
假如瞬间无穷短的时间内多次点击了`开始游戏`, 那么多次 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 协议》,转载必须注明作者和本文链接
1、使用redis锁 博客:分布式锁的实现
2、在表单生成的时候填充一个随机token,将这个token存到session中,当提交后判断token是否一致,一致则说明是第一次提交,此时删除这个token,否则的话就说明已经提交过了