数据重复提交问题

719 阅读1分钟

场景

用户添加新的商品、单据等数据

操作

1、先查询商品名称/单据号是否存在,业务校验重复性

2、如果商品/单据号存在,提示重复返回给客户端

问题

当用户网络不好,提交按钮点的很快,同一时间会造成多次提交,有一定的并发问题(多次查单号都是不存在的)。

解决

1、在web端提交后直接disable按钮

2、后台根据请求参数生成一个摘要,在一定时间(1s)内判断,如果数据相同就给过滤掉。

示例

.net过滤器统一验证

string defaultRepeatRequestKey = "cacheRequestParam:" + access_token;
int defaultTimeUnit = 2;                            // 重复请求限制时间单位:默认2秒
int repeatRequestCountPerTimeUnit = 5;              // 每个时间单位内最大重复请求限制数量 (Get 默认2秒内5次,Post 默认 2 秒内1次)
string requestParams = string.Empty;
if (actionContext.Request.Method == HttpMethod.Get)
{
    requestParams = MD5Helper.Encryption(actionContext.Request.RequestUri.Query);
}
else if (actionContext.Request.Method == HttpMethod.Post)
{
    repeatRequestCountPerTimeUnit = 1;
    requestParams = MD5Helper.Encryption(actionContext.Request.Content.ReadAsStringAsync().GetAwaiter().GetResult());
}
var repeatRequestCount = RedisHelper.HGet<int>(defaultRepeatRequestKey, requestParams);
if (repeatRequestCount > repeatRequestCountPerTimeUnit)
{
    var responseBase = new ResponseBase { IsSuccess = false, Msg = "请求正在处理,请勿频繁提交...", Code = 205 };
    actionContext.Response = new HttpResponseMessage(HttpStatusCode.ResetContent)
    {
        Content = GetStringContentResult(responseBase)
    };
}
RedisHelper.StartPipe()
    .HIncrBy(defaultRepeatRequestKey, requestParams)
    .Expire(defaultRepeatRequestKey, defaultTimeUnit)
    .EndPipe();

具体可以针对业务做相应策略,根据业务、用户