.net Core数据的幕等性
一、背景
代码实例:https://gitee.com/D_C_L/CurtainEtcAOP.git
我们实际系统中有很多操作,是不管做多少次,都应该产生一样的效果或返回一样的结果。
例如:
1. 前端重复提交选中的数据,应该后台只产生对应这个数据的一个反应结果。
2. 我们发起一笔付款请求,应该只扣用户账户一次钱,当遇到网络重发或系统bug重发,也应该只扣一次钱;
3. 发送消息,也应该只发一次,同样的短信发给用户,用户会哭的;
4. 创建业务订单,一次业务请求只能创建一个,创建多个就会出大问题。
等等很多重要的情况,这些逻辑都需要幂等的特性来支持。
二、幂等性概念
幂等(idempotent、idempotence)是一个数学与计算机学概念,常见于抽象代数中。
在编程中.一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。幂等函数,或幂等方法,是指可以使用相同参数重复执行,并能获得相同结果的函数。这些函数不会影响系统状态,也不用担心重复执行会对系统造成改变。例如,“getUsername()和setTrue()”函数就是一个幂等函数.
更复杂的操作幂等保证是利用唯一交易号(流水号)实现.
我的理解:幂等就是一个操作,不论执行多少次,产生的效果和返回的结果都是一样的
一,正式开始了
现在我们们要做一个点击按钮之后等待后台返回之后才可以再次请求方法,其他的重复请求直接进行拦截
在这里我使用拦截器进行实现(也可以使用中间件来实现),主要就是以AOP(切面编程是面向对象的优化),将一些紧密的业务进行切开,在中间进行自己的一些逻辑处理
主要的实现思路就是使用toekn+Redis缓存进行(当我们访问某个方法的时候给用户的客户端存取一个cookie)cookie里面主要是存的toekn,当我们访问接口的时候一定要带上有效的
token才能访问方法或者控制器。
客户端访问方法的时候存token到Redis里面,当请求方法的时候带上token,拦截器里面判断是不是存放在Redis里面的token如果不是的直接拦截返回,如果带上的是有效的token删除旧token
生成一个新的token存放在cookie里面,存到Redis,给第二次请求发放token。
代码理解:
//视图页面
public partial class HomeController : Controller
{
private readonly RedisHelp cache = new RedisHelp();
/// <summary>
/// 首页 获取token
/// </summary>
/// <returns></returns>
[NoSign]
public IActionResult Index()
{
string token = Guid.NewGuid().ToString();
HttpContext.Response.Cookies.Append("token", token);
cache.SetValue("token", token);
return View();
}
}
当浏览器访问这个视图的时候给他发放一个token。
这里存在cooke的好处就是,下一次请求会直接带上上一次发放的Toekn,我们在前台就不需要去做任何操作了,这样拦截器才能算上是一个独立的模块。
我们需要访问这个接口,保证同时点击的时候只能有一次
/// <summary>
/// 接口控制器
/// </summary>
public partial class HomeController : Controller
{
/// <summary>
/// 接受提交请求
/// </summary>
/// <returns></returns>
public JsonResult Submit()
{
ResponseJson responseJson = new ResponseJson();
responseJson.msg = "更新了token";
return Json(responseJson);
}
}
下面就是拦截器的代码
/// <summary>
/// 适合全局的
/// </summary>
public class SignFilter : ActionFilterAttribute
{
private RedisHelp cache = new RedisHelp();
/// <summary>
/// 请求之前
/// </summary>
/// <param name="context"></param>
public override void OnActionExecuting(ActionExecutingContext context)
{
// 判断是否检查登陆
var noNeedCheck = false;
if (context.ActionDescriptor is ControllerActionDescriptor controllerActionDescriptor)
{
noNeedCheck = controllerActionDescriptor.MethodInfo.GetCustomAttributes(inherit: true)
.Any(a => a.GetType().Equals(typeof(NoSignAttribute)));
}
if (noNeedCheck)return; ResponseJson responseJson = new ResponseJson();
var token = context.HttpContext.Request.Cookies["token"];
#region 判断数据有效性
if (string.IsNullOrWhiteSpace(token))
{
responseJson.msg = "toekn不能空";
context.Result = new JsonResult(responseJson);
return;
} else if (cache.GetValue("token") ==null) {
responseJson.msg = "toekn不能空";
context.Result = new JsonResult(responseJson);
return;
} else if (!cache.DeleteKey("token")) {
responseJson.msg = "token已不存在";
context.Result = new JsonResult(responseJson);
return;
}
#endregion
base.OnActionExecuting(context);
} /// <summary>
/// 请求过了之后,在去分发token
/// </summary>
/// <param name="context"></param>
public override void OnActionExecuted(ActionExecutedContext context)
{
//随机值
string redisToken = Guid.NewGuid().ToString() + new Random().Next(, );
context.HttpContext.Response.Cookies.Append("token", redisToken);
//初使化并设置Cookie的名称
cache.SetValue("token", redisToken);
}
} /// <summary>
/// 不需要登陆的地方加个特性
/// </summary>
public class NoSignAttribute : ActionFilterAttribute { }

但是这个只适合于个人在点击的时候的,下次我分享一下多人的模式。
.net Core数据的幕等性的更多相关文章
- EF Core 数据变更自动审计设计
EF Core 数据变更自动审计设计 Intro 有的时候我们需要知道每个数据表的变更记录以便做一些数据审计,数据恢复以及数据同步等之类的事情, EF 自带了对象追踪,使得我们可以很方便的做一些审计工 ...
- WCF初探-17:WCF数据协定之等效性
数据协定等效性特点概述 对于客户端要将某种类型的数据成功发送到服务,或者服务要将数据成功发送到客户端的情况,接收端上并不一定必须存在此发送数据类型. 唯一的要求是两种类型的数据协定应该等效. 要使数据 ...
- WCF技术剖析之十六:数据契约的等效性和版本控制
原文:WCF技术剖析之十六:数据契约的等效性和版本控制 数据契约是对用于交换的数据结构的描述,是数据序列化和反序列化的依据.在一个WCF应用中,客户端和服务端必须通过等效的数据契约方能进行有效的数据交 ...
- [EF Core]数据迁移(二)
摘要 在实际项目中,大多都需要对业务逻辑以及操作数据库的逻辑进行分成操作,这个时候该如何进行数据的迁移呢? 步骤 上篇文章:EF Core数据迁移操作 比如,我们将数据上下文放在了Data层. 看一下 ...
- C/C++ socket编程教程之九:TCP的粘包问题以及数据的无边界性
C/C++ socket编程教程之九:TCP的粘包问题以及数据的无边界性 上节我们讲到了socket缓冲区和数据的传递过程,可以看到数据的接收和发送是无关的,read()/recv() 函数不管数据发 ...
- 探讨NET Core数据进行3DES加密或解密弱密钥问题
前言 之前写过一篇<探讨.NET Core数据进行3DES加密和解密问题>,最近看到有人提出弱密钥问题,换个强密钥不就完了吗,猜测可能是与第三方对接导致很无奈不能更换密钥,所以产生本文解决 ...
- 云原生ASP.NET Core程序的可监测性和可观察性
分布式应用程序很复杂,给开发人员调试和修复生产问题带来了一系列挑战.尽管微服务架构可帮助维持一支规模较小,可以自主工作并专注于独立业务团队,但由于其分布式性质,它带来了新的挑战.例如,在业务交易过程中 ...
- EntityFramework Core数据查询
前言 本节我们再来讲讲EF Core,本节算是回归基础吧,当前项目EF Core还是处于1.1版本中,后续等待.net core等版本稳定了全部会更新到2.0版本中,到时再来更新相关文章分享给大家. ...
- ASP.NET Core 入门教程 8、ASP.NET Core + Entity Framework Core 数据访问入门
一.前言 1.本教程主要内容 ASP.NET Core MVC 集成 EF Core 介绍&操作步骤 ASP.NET Core MVC 使用 EF Core + Linq to Entity ...
随机推荐
- 《Java基础知识》Java集合(Collection)
作为一个Developer,Java集合类是我们在工作中运用最多的.最频繁的类.相比于数组(Array)来说,集合类的长度可变,更加适合于现代开发需求: Java集合就像一个容器,可以存储任何类型的数 ...
- Hack the Zico2 VM (CTF Challenge)
下载链接: Download this VM here: https://download.vulnhub.com/zico/zico2.ova 端口扫描: ╰─ nmap -p1-65535 -sV ...
- PHP 正则匹配h1的数据报错 preg_match(): Unknown modifier 'h' in
问题: $str = "<h1>this is test msg</h1>"; $ruler = "/^<h1>(.*?)</h ...
- Django的Form验证(2)
Django的Form验证(2) Form的含义及作用: 用于验证用户请求数据合法性的一个组件(校验数据的合法性) Django的Form实现步骤: 创建一个验证用户请求的模板 from django ...
- 2019icpc银川站 复现赛
打了计蒜客上的银川重现赛,总体感觉难度上确实比平时区域赛要低上一些. 这里补一下F题和G题的思路和代码. upd:I题也补了,理解差不多都在注释里. F题 做法,玩一下n=10的样例就出 ...
- 一文读懂分布式任务调度平台XXL-JOB
本文主要介绍分布式任务调度平台XXL-JOB(v2.1.0版本),包括功能特性.实现原理.优缺点.同类框架比较等 基本介绍 项目开发中,常常以下场景需要分布式任务调度: 同一服务多个实例的任务存在互斥 ...
- python高阶函数—filter
python内置了一个filter函数,用于过滤序列.和map函数类似,filter()函数也接受一个函数和一个序列.只不过filter函数中是把函数依次作用于序列中的每一个元素,如果是True则保留 ...
- C#封装继承
面向对象开发有三大特性(特点 / 特征) : 封装, 继承, 多态.我们今天主要讨论封装和继承,多态会在下篇中讨论. 一.封装: 所谓封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法 ...
- C# FlagAttriute 的 小妙招
FlagAttriute ,指示可将枚举视为位域(即一组标志). 官网中文解说:https://docs.microsoft.com/zh-cn/dotnet/api/system.flagsattr ...
- ESPCMS P8 stable version Front-end reflective xss
Download the source code first In the directory espcms_web\espcms_load.php line 67 if (!is_file($mod ...