redis 业务锁 not exist 模式
背景:
业务核心模块只能提交一次,原实现方案 前端加提交限制、后端加数据库业务逻辑判定,结果失效,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 模式的更多相关文章
- springBoot实现redis分布式锁
参考:https://blog.csdn.net/weixin_44634197/article/details/108308395 .. 使用redis的set命令带NX(not exist)参数实 ...
- Redis 分布式锁|从青铜到钻石的五种演进方案
缓存系列文章: 缓存实战(一):20 图 |6 千字|缓存实战(上篇) 缓存实战(二):Redis 分布式锁|从青铜到钻石的五种演进方案 缓存实战(三):分布式锁中的王者方案 - Redisson 上 ...
- Redis分布式锁 (图解-秒懂-史上最全)
文章很长,而且持续更新,建议收藏起来,慢慢读! 高并发 发烧友社群:疯狂创客圈(总入口) 奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : 极致经典 + 社群大片好评 < Java 高并发 三 ...
- spring boot redis分布式锁
随着现在分布式架构越来越盛行,在很多场景下需要使用到分布式锁.分布式锁的实现有很多种,比如基于数据库. zookeeper 等,本文主要介绍使用 Redis 做分布式锁的方式,并封装成spring b ...
- 4、redis 分布式锁
1. 前言 关于分布式锁的实现,目前常用的方案有以下三类: 数据库乐观锁: 基于分布式缓存实现的锁服务,典型代表有 Redis 和基于 Redis 的 RedLock: 基于分布式一致性算法实现的锁服 ...
- Redlock(redis分布式锁)原理分析
Redlock:全名叫做 Redis Distributed Lock;即使用redis实现的分布式锁: 使用场景:多个服务间保证同一时刻同一时间段内同一用户只能有一个请求(防止关键业务出现并发攻击) ...
- Redis分布式锁的实现
前段时间,我在的项目组准备做一个类似美团外卖的拼手气红包[第X个领取的人红包最大],基本功能实现后,就要考虑这一操作在短时间内多个用户争抢同一资源的并发问题了,类似于很多应用如淘宝.京东的秒杀活动场景 ...
- redis分布式锁redisson
原文:https://blog.csdn.net/Kincym/article/details/78697472 关于redisson的源代码请参考官网:https://github.com/redi ...
- Redisson实现Redis分布式锁的N种姿势(转)
Redis几种架构 Redis发展到现在,几种常见的部署架构有: 单机模式: 主从模式: 哨兵模式: 集群模式: 我们首先基于这些架构讲解Redisson普通分布式锁实现,需要注意的是,只有充分了解普 ...
随机推荐
- jq + 面向对象实现拼图游戏
jq + 面向对象实现拼图游戏 知识点 拖拽事件 es6面向对象 jquery事件 效果图 html: <div class="wraper"> <div cla ...
- ubuntu 使用alias 新增删除命令del替代rm
alias del=trash #del命令别名删除文件至回收站 alias lt='ls /tmp' #lt命令显示回收站中的文件 alias cle=cleartrash #cle清除tmp文件夹 ...
- SAP云平台上的SSO Principal Propagation设置
我今天试图使用SAP云平台的SAP WebIDE Fullstack时,发现打不开, 遇到如下错误信息: You are not authorized to work with SAP Web IDE ...
- 学而不思则罔 - SAP云平台ABAP编程环境的由来和适用场景
最近Jerry写了一系列关于SAP云平台ABAP编程环境的技术文章,这些文章都是围绕着在云上的ABAP编程环境的具体知识点来分享,比如要完成一个具体的开发需求,所需要的编程步骤.这些文章陆续收到一些读 ...
- 使用gulp构建项目
gulp.js作为一个前端构建工具,类似于webpack.Grountjs.rollupjs,不过相对于其他几种打包工具,gulp的使用更轻量,配置更简单,打包速度更快,今天不说他们几个的区别,也不说 ...
- MySQL Connection--使用tcpkill杀掉MySQL活跃连接
当MySQL连接被打满,连管理员也无法本地登录时,可以考虑使用tcpkill杀掉一些应用服务器创建的连接. CentOS 6安装tcpkill rpm安装包: libnids-1.24-1.el6.x ...
- Android笔记(五十五) Android四大组件之一——ContentProvider,使用系统提供的ContentProvider
因为在Android中,存储系统联系人姓名和电话是存在与不同的ContentProvider中的,具体如何查找,可以从Android的源代码中查看,在android.providers包中列出了所有系 ...
- 14.专攻python和centos7
大牛博客:https://blog.51cto.com/yangrong/p5 用户接口应用程序: [root@python01 ~]# ps aux|grep bashroot 23860 ...
- 迷你商城后台管理系统————stage1需求分析
PS:迷你商城后台管理系统---需求分析.docx下载~click me 迷你商城后台管理系统-- 需求分析 1. 引言 作为互联网热潮的崛起,消费者们的普遍差异化,实体商城要想在互联网的浪潮中继续发 ...
- 清除PLSQL Developer访问数据库连接的历史记录
1.C盘下 路径: C:\Users\JourneyOfFlower\AppData\Roaming\PLSQL Developer 12\Preferences\JourneyOfFlower\ J ...