背景:

业务核心模块只能提交一次,原实现方案 前端加提交限制、后端加数据库业务逻辑判定,结果失效,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<T>(string key, T objectValue, long lNumofSeconds = , StackExchange.Redis.When when =When.Always)
{
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<T>(objectValue), new TimeSpan?(TimeSpan.FromSeconds((double)lNumofSeconds)), when, CommandFlags.None);
}
return ManagerMaster.GetDatabase(-, null).StringSet(key, ConvertJson<T>(objectValue), null, when, CommandFlags.None);
}
catch (Exception) { result = false; }
return result;
}
namespace StackExchange.Redis
{
public enum When
{
Always,
Exists,
NotExists,
}
}

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

 /// <summary>
/// 判定缓存是否存在
/// 不存在就添加缓存
/// </summary>
/// <param name="redisKey"></param>
/// <param name="inputValue">redis值</param>
/// <param name="timeSecond">过期时间/秒</param>
/// <param name="cacheType">{0:cache;2=redis};默认redis</param>
/// <returns>true 代表存在redis false 代表不存在redis 自动写入</returns>
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秒,方法执行完毕自动释放

/// <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"/>

redis 业务锁 not exist 模式的更多相关文章

  1. springBoot实现redis分布式锁

    参考:https://blog.csdn.net/weixin_44634197/article/details/108308395 .. 使用redis的set命令带NX(not exist)参数实 ...

  2. Redis 分布式锁|从青铜到钻石的五种演进方案

    缓存系列文章: 缓存实战(一):20 图 |6 千字|缓存实战(上篇) 缓存实战(二):Redis 分布式锁|从青铜到钻石的五种演进方案 缓存实战(三):分布式锁中的王者方案 - Redisson 上 ...

  3. Redis分布式锁 (图解-秒懂-史上最全)

    文章很长,而且持续更新,建议收藏起来,慢慢读! 高并发 发烧友社群:疯狂创客圈(总入口) 奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : 极致经典 + 社群大片好评 < Java 高并发 三 ...

  4. spring boot redis分布式锁

    随着现在分布式架构越来越盛行,在很多场景下需要使用到分布式锁.分布式锁的实现有很多种,比如基于数据库. zookeeper 等,本文主要介绍使用 Redis 做分布式锁的方式,并封装成spring b ...

  5. 4、redis 分布式锁

    1. 前言 关于分布式锁的实现,目前常用的方案有以下三类: 数据库乐观锁: 基于分布式缓存实现的锁服务,典型代表有 Redis 和基于 Redis 的 RedLock: 基于分布式一致性算法实现的锁服 ...

  6. Redlock(redis分布式锁)原理分析

    Redlock:全名叫做 Redis Distributed Lock;即使用redis实现的分布式锁: 使用场景:多个服务间保证同一时刻同一时间段内同一用户只能有一个请求(防止关键业务出现并发攻击) ...

  7. Redis分布式锁的实现

    前段时间,我在的项目组准备做一个类似美团外卖的拼手气红包[第X个领取的人红包最大],基本功能实现后,就要考虑这一操作在短时间内多个用户争抢同一资源的并发问题了,类似于很多应用如淘宝.京东的秒杀活动场景 ...

  8. redis分布式锁redisson

    原文:https://blog.csdn.net/Kincym/article/details/78697472 关于redisson的源代码请参考官网:https://github.com/redi ...

  9. Redisson实现Redis分布式锁的N种姿势(转)

    Redis几种架构 Redis发展到现在,几种常见的部署架构有: 单机模式: 主从模式: 哨兵模式: 集群模式: 我们首先基于这些架构讲解Redisson普通分布式锁实现,需要注意的是,只有充分了解普 ...

随机推荐

  1. Git使用整理

    [本文由水木桶首发于博客园,原文地址:https://www.cnblogs.com/shuimutong/p/11404664.html,未接允许,严禁转载] 背景 很久之前使用的是svn,直接在E ...

  2. Node学习之(第三章:仿Apache显示目录列表的功能)

    前言 今天咱们用Node.js中的核心模块以及上节学习的模板引擎art-template来实现服务器软件Apache的大体功能.用过Apache的朋友都知道,我们只需把本地文件放置在Apache的ww ...

  3. grant_type为client_credentials和password二者的区别

    最近工作中需要使用到oauth,注意到oauth客户端的grant_type值可以指定为client_credentials和password两种,很好奇所以网上搜索了一下,发现stackoverfl ...

  4. MaxScale ERROR 2006 (HY000): MySQL server has gone away

    Error: MaxScale cannot be run as root.Failed to write child process message!解决办法:# maxscale -f /etc/ ...

  5. mysql遇到时区问题的坑(Java解决方案)

    最近项目遇到一个坑,就是server和db之间存在时区问题,本人的db是utc时间, 可以使用代码设置时区来解决,本人这里使用joda三方包,joda蛮好用的,具体用法这里不做详细描述. 先引入pom ...

  6. mysql学习之基础篇01

    大概在一周前看了燕十八老师讲解的mysql数据库视频,也跟着学了一周,我就想把我这一周所学的知识跟大家分享一下:因为是第一次写博客,所以可能会写的很烂,请大家多多包涵.文章中有不对的地方还请大家指出来 ...

  7. PCM时序

    PCM(Pulse Code Modulation),脉冲编码调制,PCM总线用于传输数字语音信号,包括4根信号线:FSYNC(同步)/PCLK(时钟)/DTX(发送)/DRX(接收) PCM分为Ma ...

  8. 1.后期特效合成AE概述&&工作流程&&磁盘缓存清理

    1.简介: After Effects:是一款专业的后期制作与特效合成软件: 2.AE界面介绍  2.1 项目面板   2.2 合成预览面板   2.3 时间线面板     2.4 辅助面板    2 ...

  9. dict排序

    根据dict值排序 c = {1:10,2:9,3:8} c = sorted(c.items(), key=lambda d: d[1], reverse=1) reverse=1 从大到小排列 起 ...

  10. python算法与数据结构-算法介绍(31)

    一.算法和数据结构 什么是算法和数据结构?如果将最终写好运行的程序比作战场,我们程序员便是指挥作战的将军,而我们所写的代码便是士兵和武器. 那么数据结构和算法是什么?答曰:兵法!故,数据结构和算法是一 ...