一、背景

代码实例: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数据的幕等性的更多相关文章

  1. EF Core 数据变更自动审计设计

    EF Core 数据变更自动审计设计 Intro 有的时候我们需要知道每个数据表的变更记录以便做一些数据审计,数据恢复以及数据同步等之类的事情, EF 自带了对象追踪,使得我们可以很方便的做一些审计工 ...

  2. WCF初探-17:WCF数据协定之等效性

    数据协定等效性特点概述 对于客户端要将某种类型的数据成功发送到服务,或者服务要将数据成功发送到客户端的情况,接收端上并不一定必须存在此发送数据类型. 唯一的要求是两种类型的数据协定应该等效. 要使数据 ...

  3. WCF技术剖析之十六:数据契约的等效性和版本控制

    原文:WCF技术剖析之十六:数据契约的等效性和版本控制 数据契约是对用于交换的数据结构的描述,是数据序列化和反序列化的依据.在一个WCF应用中,客户端和服务端必须通过等效的数据契约方能进行有效的数据交 ...

  4. [EF Core]数据迁移(二)

    摘要 在实际项目中,大多都需要对业务逻辑以及操作数据库的逻辑进行分成操作,这个时候该如何进行数据的迁移呢? 步骤 上篇文章:EF Core数据迁移操作 比如,我们将数据上下文放在了Data层. 看一下 ...

  5. C/C++ socket编程教程之九:TCP的粘包问题以及数据的无边界性

    C/C++ socket编程教程之九:TCP的粘包问题以及数据的无边界性 上节我们讲到了socket缓冲区和数据的传递过程,可以看到数据的接收和发送是无关的,read()/recv() 函数不管数据发 ...

  6. 探讨NET Core数据进行3DES加密或解密弱密钥问题

    前言 之前写过一篇<探讨.NET Core数据进行3DES加密和解密问题>,最近看到有人提出弱密钥问题,换个强密钥不就完了吗,猜测可能是与第三方对接导致很无奈不能更换密钥,所以产生本文解决 ...

  7. 云原生ASP.NET Core程序的可监测性和可观察性

    分布式应用程序很复杂,给开发人员调试和修复生产问题带来了一系列挑战.尽管微服务架构可帮助维持一支规模较小,可以自主工作并专注于独立业务团队,但由于其分布式性质,它带来了新的挑战.例如,在业务交易过程中 ...

  8. EntityFramework Core数据查询

    前言 本节我们再来讲讲EF Core,本节算是回归基础吧,当前项目EF Core还是处于1.1版本中,后续等待.net core等版本稳定了全部会更新到2.0版本中,到时再来更新相关文章分享给大家. ...

  9. 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 ...

随机推荐

  1. SpringBoot电商项目实战 — ElasticSearch接入实现

    如今在一些中大型网站中,搜索引擎已是必不可少的内容了.首先我们看看搜索引擎到底是什么呢?搜索引擎,就是根据用户需求与一定算法,运用特定策略从互联网检索出制定信息反馈给用户的一门检索技术.搜索引擎依托于 ...

  2. C# 几种常见数据结构

    一.内存上连续存储,节约空间,可以索引访问,读取快,增删慢 Array:在内存上连续分配的,而且元素类型是一样的,可以坐标访问;读取快--增删慢,长度不变 { //Array:在内存上连续分配的,而且 ...

  3. 萌新入门Github请看这里,学不会远程教

    一些废话 本文的主旨是为初次接触Github的同学提供一个入门的教程,如果你已经是Github老鸟,可以忽略本文哦,另外本文只是抛砖引玉,其实最好的教程是官方文档!!! Github官网 Github ...

  4. c++-多态的学习

    多态的基本介绍 多态基础 面向对象新求 C++编译器提供的多态解决方案 多态意义.多态成立的是三个条件 多态理论基础 多态面试题强化 多态的理解 C++编译器如何实现多态 重载重写重定义 虚析构函数 ...

  5. JS---DOM---为元素解绑事件

    解绑事件 注意:用什么方式绑定事件, 就应该用对应的方式解绑事件 1.解绑事件 对象.on事件名字=事件处理函数--->绑定事件 对象.on事件名字=null;   //1 对象.on事件名字= ...

  6. WPF布局容器

    1.StackPanel:堆栈面板,通过Orientation属性设置子元素的布局排列方向为“Vertical”(垂直)和“Horizontal”(水平),不写其默认值为“Vertical”,当设置为 ...

  7. 网页解析库-Xpath语法

    网页解析库 简介 除了正则表达式外,还有其他方便快捷的页面解析工具 如:lxml (xpath语法) bs4 pyquery等 Xpath 全称XML Path Language, 即XML路径语言, ...

  8. 《Web Development with Go》Mangodb查询一条记录

    select加where package main import ( "fmt" "log" "time" "gopkg.in/m ...

  9. 痞子衡嵌入式:飞思卡尔i.MX RTyyyy系列MCU启动那些事(1)- Boot简介

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是飞思卡尔i.MX RTyyyy系列MCU的BootROM功能简介. 截止目前为止i.MX RTyyyy系列已公布的芯片有三款i.MXRT ...

  10. Spring 核心技术与产品理念剖析【下】

    3. Spring Cloud 蝶变重生 Spring 框架的升级演进都是围绕分层架构进行的,从简单到复杂,再回到简单的过程.如果我们没有经历过 Spring 最开始繁琐的配置,然后一步步精简,就根本 ...