zoukankan      html  css  js  c++  java
  • redis 业务锁 not exist 模式

    背景:

    业务核心模块只能提交一次,原实现方案 前端加提交限制、后端加数据库业务逻辑判定,结果失效,api站点部署多台负载,切方法需要强求第三方接口 响应时间较慢 ,故放弃lock。

    解决方案:redis业务锁。

    一、原理

    1:利用redis原子性解决并发问题

    2:利用redis集群署解决分布式部署问题

    3:利用redis性能快解决时间消耗问题

    4:利用redis过期时间解决死锁问题

    5:利用rediskey唯一性解决互斥问题

    问题:超时时间存在误差

    二、基础方法

    2.1RedisManager 中重构Set,可以设置When 属性,Always 总是保存,Exists 存在时保存,NotExists 不存在时保存。返回值中truefalse代表是否操作。

    设置notExists模式可以判定redis中是否存在值

     1 public static bool Set<T>(string key, T objectValue, long lNumofSeconds = 0, StackExchange.Redis.When when =When.Always)
     2         {
     3             if (!Enum.IsDefined(typeof(When), when))
     4                 throw new InvalidEnumArgumentException(nameof(when), (int) when, typeof(When));
     5             bool result = false;
     6             try
     7             {
     8                 key = redisConfigInfo.KeySuffix + key;
     9                 if (lNumofSeconds > 0L)
    10                 {
    11                     return ManagerMaster.GetDatabase(-1, null).StringSet(key, ConvertJson<T>(objectValue), new TimeSpan?(TimeSpan.FromSeconds((double)lNumofSeconds)), when, CommandFlags.None);
    12                 }
    13                 return ManagerMaster.GetDatabase(-1, null).StringSet(key, ConvertJson<T>(objectValue), null, when, CommandFlags.None);
    14             }
    15             catch (Exception) { result = false; }
    16             return result;
    17         }
    namespace StackExchange.Redis
    {
      public enum When
      {
        Always,
        Exists,
        NotExists,
      }
    }

    2.2:判定是否存在redis缓存 ,如果存在则返回true 如果不存在就返回false并保存值

     1 /// <summary>
     2         /// 判定缓存是否存在
     3         /// 不存在就添加缓存
     4         /// </summary>
     5         /// <param name="redisKey"></param>
     6         /// <param name="inputValue">redis值</param>
     7         /// <param name="timeSecond">过期时间/秒</param>
     8         /// <param name="cacheType">{0:cache;2=redis};默认redis</param>
     9         /// <returns>true 代表存在redis false 代表不存在redis 自动写入</returns>
    10         public static bool CheckRedisNoExistSet(string redisKey, string inputValue, int timeSecond = 120,int cacheType=1)
    11         {
    12             //redis写 NX-- Only set the key if it does not already exist.
    13             //true写成功 无数据 写入,false 没写 或者异常  
    14             return !RedisManager.Set(redisKey, inputValue, timeSecond, When.NotExists);
    15         }

    三、应用

    通过redis 来实现业务锁功能

    1:最小单位可是精确到某一个表的ID ,例如:reportID

    2:如果正在处理这个案件则阻止其他并发操作

    3:自动过期时间为120秒,方法执行完毕自动释放

    /// <summary>
            /// 正式全部提交
            /// 1.返回code=0表示存在重复案件
            /// 2.首次IsContinue传0,继续提交IsContinue传1
            /// </summary>
            /// <param name="request"></param>
            /// <returns></returns>
            [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;
            }
    <!--全部提交业务锁-->
      <add key="CenterSubmitAllSimpleCase" value="fc_centerSubmitAllSimpleCase_{0}_feiCheRedis20"/>
  • 相关阅读:
    [转]The Machine SID Duplication Myth (and Why Sysprep Matters)
    The Machine SID Duplication Myth (and Why Sysprep Matters)
    [转]Shell(Bash) mysql数据库操作
    [转]GNU Sourcehighlight 语法高亮代码
    [原]DRBD双主模式问题
    mpstat
    DRBD试用
    drbd双主模式问题
    虚IP的添加和删除
    为什么5%的技术人员开发效率是其他95%的20倍?
  • 原文地址:https://www.cnblogs.com/zhaokunbokeyuan256/p/10894945.html
Copyright © 2011-2022 走看看