学习尚硅谷-谷粒商城记录的笔记
1,使用Token -redis/session
访问新增页面的时候后台生成一个uuid,同时将uuid存储在redis中key为每个用户id,页面携带上uuid,提交时再返回uuid;用于与当前用户下uuid比较,对比相同删除redis中uuid继续业务数据保存,对比不相同(redis没有值)返回错误提示;
要保证:redis.get(token) 、token.equals、redis.del(token)如果这三个操作是原子操作;否则高并发下,都 get 到同样的数据,判断都成功,继续业务并发执行;这样还会造成数据重复
可以在 redis 使用 lua 脚本完成这个原子操作
if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end
// 防重令牌--存储redis
String token = UUID.randomUUID().toString().replace("-", "");
redisTemplate.opsForValue().set(OrderConstant.USER_ORDER_TOKEN_PREFIX + memberResponseVo.getId(), token, 30, TimeUnit.MINUTES);
confirmVo.setOrderToken(token); //发送给页面,提交表单的时候上携带上
提交表单-校验token
//1. 验证防重令牌
MemberResponseVo memberResponseVo = LoginInterceptor.loginUser.get();
String script= "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
Long execute = redisTemplate.execute(new DefaultRedisScript<>(script,Long.class), Arrays.asList(OrderConstant.USER_ORDER_TOKEN_PREFIX + memberResponseVo.getId()), submitVo.getOrderToken());
if (execute == 0L) {
//1.1 防重令牌验证失败
responseVo.setCode(1);
return responseVo;
}else {
//业务处理-保存数据
}
2,数据库表设置- 列唯一约束
插入数据,应该按照唯一索引进行插入,比如订单号,相同的订单就不可能有两条记录插入。 我们在数据库层面防止重复。 这个机制是利用了数据库的主键唯一约束的特性,解决了在 insert 场景时幂等问题。但主键 的要求不是自增的主键,这样就需要业务生成全局唯一的主键。 如果是分库分表场景下,路由规则要保证相同请求下,落地在同一个数据库和同一表中,要 不然数据库主键约束就不起效果了,因为是不同的数据库和表主键不相关。
3,业务层分布式锁
如果多个机器可能在同一时间同时处理相同的数据,比如多台机器定时任务都拿到了相同数 据处理,我们就可以加分布式锁,锁定此数据,处理完成后释放锁。获取到锁的必须先判断 这个数据是否被处理过。
4,数据MD5-唯一处理
很多数据需要处理,只能被处理一次,比如我们可以计算数据的 MD5 将其放入 redis 的 set ,
每次处理数据,先看这个 MD5 是否已经存在,存在就不处理。
5, 页面按钮点击之后 解绑点击事件
$("#uploadBtn").removeAttr("onclick");//点击一次之后解除点击事件$("#uploadBtn").attr("onclick","saveFile(this);");//绑定点击事件-异常或已处理返回时