一、背景

代码实例: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. [ASP.NET Core 3框架揭秘] 依赖注入[9]:实现概述

    <服务注册>.<服务消费>和<生命周期>主要从实现原理的角度对.NET Core的依赖注入框架进行了介绍,接下来更进一步,看看该框架的总体设计和实现.在过去的多个版 ...

  2. git项目创建及在idea工具中使用

    1.安装git管理工具 2.在自己github账号上创建一个项目仓库,比如我创建的是renrenView 网页翻译如下: 参数解析如下: 3.本地项目同步到远程仓库步骤 在本地初始化git项目 git ...

  3. Sqlite—数据库备份与恢复

    数据库备份 例如:备份 /www/wwwroot 下面的 task.db 数据库 1.进入数据库 [root@localhost ~]# sqlite3 /www/wwwroot/task.db 2. ...

  4. 面试连环炮系列(十二):说说Atomiclnteger的使用场景

    说说Atomiclnteger的使用场景 AtomicInteger提供原子操作来进行Integer的使用,适合并发情况下的使用,比如两个线程对同一个整数累加. 为什么Atomiclnteger是线程 ...

  5. 集合系列 Queue(十):LinkedList

    我们之前在说到 List 集合的时候已经说过 LinkedList 了.但 LinkedList 不仅仅是一个 List 集合实现,其还是一个双向队列实现. public class LinkedLi ...

  6. Mysql性能优化之参数配置(转)

    前言: Mysql作为数据库中广泛应用的开源产品,需要面对不同的生产压力,而有些性能问题通过配置优化就可以得到解决,优化可以分为几个方向:1.优化参数配置.2.优化数据库索引.3.优化数据库结构,如分 ...

  7. Python爬虫基础——正则表达式

    说到爬虫,不可避免的会牵涉到正则表达式. 因为你需要清晰地知道你需要爬取什么信息?它们有什么共同点?可以怎么去表示它们? 而这些,都需要我们熟悉正则表达,才能更好地去提取. 先简单复习一下各表达式所代 ...

  8. (八十)c#Winform自定义控件-分割线标签-HZHControls

    官网 http://www.hzhcontrols.com 前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kww ...

  9. C# WinForm界面美化--使用IrisSkin实现换肤功能

    WinForm界面使用IrisSkin,可以说做到了一键美化,当然美化的效果仁者见仁智者见智,可以挑选自己喜欢的. 1.IrisSkin下载地址:https://www.cr173.com/soft/ ...

  10. mysql存储4字节的表情包数据报异常_Emoji表情包_Incorrect string value: '\xF0\x9F\x98\x84\xF0\x9F

    本文章转载自:https://www.cnblogs.com/coprince/p/7485968.html 原文如下: 问题描述:从新浪微博抓取消息保存到MySQL数据中,对应数据库字段为varch ...