业务核心模块只能提交一次,原实现方案 前端加提交限制、后端加数据库业务逻辑判定,结果失效,api站点部署多台负载,切方法需要强求第三方接口 响应时间较慢 ,故放弃lock。
解决方案:redis业务锁。
1:利用redis原子性解决并发问题
2:利用redis集群署解决分布式部署问题
3:利用redis性能快解决时间消耗问题
4:利用redis过期时间解决死锁问题
5:利用rediskey唯一性解决互斥问题
问题:超时时间存在误差
2.1:RedisManager 中重构Set,可以设置When 属性,Always 总是保存,Exists 存在时保存,NotExists 不存在时保存。返回值中true与false代表是否操作。
设置notExists模式可以判定redis中是否存在值
public static bool Set
{
if (!Enum.IsDefined(typeof(When), when))
throw new InvalidEnumArgumentException(nameof(when), (int) when, typeof(When));
bool result = false;
try
{
key = redisConfigInfo.KeySuffix + key;
if (lNumofSeconds > 0L)
{
return ManagerMaster.GetDatabase(-, null).StringSet(key, ConvertJson
}
return ManagerMaster.GetDatabase(-, null).StringSet(key, ConvertJson
}
catch (Exception) { result = false; }
return result;
}
namespace StackExchange.Redis
{
public enum When
{
Always,
Exists,
NotExists,
}
}
2.2:判定是否存在redis缓存 ,如果存在则返回true 如果不存在就返回false并保存值
///
///
/// redis值
/// 过期时间/秒
/// {0:cache;2=redis};默认redis
///
public static bool CheckRedisNoExistSet(string redisKey, string inputValue, int timeSecond = ,int cacheType=)
{
//redis写 NX-- Only set the key if it does not already exist.
//true写成功 无数据 写入,false 没写 或者异常
return !RedisManager.Set(redisKey, inputValue, timeSecond, When.NotExists);
}
通过redis 来实现业务锁功能
1:最小单位可是精确到某一个表的ID ,例如:reportID
2:如果正在处理这个案件则阻止其他并发操作
3:自动过期时间为120秒,方法执行完毕自动释放
///
///
///
[HttpPost, Log("全部提交")]
public BaseResponse CenterSubmitAllSimpleCase([FromBody]CenterSubmitAllSimpleCaseRequest request)
{
var redisKey = string.Format(ConfigurationManager.AppSettings["CenterSubmitAllSimpleCase"], request.ReportId.ToString());
if (CacheProvider.CheckRedisNoExistSet(redisKey, request.ReportId.ToString()))
{
return BaseResponse.GetBaseResponse(BusinessStatusType.Failed, "请勿重复提交");
}
var centerFlow = _centerFlowService.QueryCenterFlowByReportId(request.ReportId).Any(e => e.Status == (int)SubmitCenterStatus.提交中);
if (centerFlow)
return BaseResponse.GetBaseResponse(BusinessStatusType.Failed, "请勿重复提交");
request.CenterSubmitType = CenterSubmitType.全部提交;
BaseResponse result = _callBackService.SubmitCompleteToCenter(request);
CacheProvider.Remove(redisKey);
return result;
}
手机扫一扫
移动阅读更方便
你可能感兴趣的文章