.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 ...
随机推荐
- 在MySQL中group by 是什么意思
mysql语法中group by是什么意思? 在百度中搜索半天,最后找到一篇解释比较好的(不是博文,是百度知道,很郁闷那么多网友怎么就没人解释的清楚),链接如下: http://zhidao.baid ...
- C++错误unresolved external symbol _WinMain@16
C++错误unresolved external symbol _WinMain@16 Linking... LIBCD.lib(wincrt0.obj) : error LNK2001: unre ...
- 基于 TrueLicense 的项目证书验证
一.简述 开发的软件产品在交付使用的时候,往往有一段时间的试用期,这期间我们不希望自己的代码被客户二次拷贝,这个时候 license 就派上用场了,license 的功能包括设定有效期.绑定 ip.绑 ...
- Wonder发布v1.1正式版本,新增资产预览、脚本、AssetBundle等
更新说明 本次版本重点增加了脚本组件,并且实现了类似于unity的AssetBundle,支持动态加载场景和资源. 相关链接 官网 Wonder官方QQ群: 106047770 相关资料 Wonder ...
- Github挂载大文件解决方案
正常情况下,我们上传代码之类的文本文件,都不会太大,可以直接通过[Upload Files]选项直接上传. 但是这样的操作仅限文件大小在25MB以内. 如果你选择的文件超过25MB,那么Github会 ...
- 服务器(VPS)被墙怎么办?
比如开发接口用的临时服务器被墙,就可以使用以下方法之一. 方法一(推荐) 为你的服务器分配一个浮动IP 等于给你的 droplet 增加一个新的 ip,我们以后访问这个新的ip就ok了. 直到下一次被 ...
- 【MySQL】LIMIT以及LIMIT OFFSET
LIMIT两种方法: 两种方法: ()LIMIT A; #表示从第一条记录开始取A条记录: ()LIMIT A,B; #参数A为可选参数,表示跳过A条数据(默认为0) #参数B为必选参数,表示取B行数 ...
- pycharm安装第三方包问题解决
pycharm安装第三方包问题解决 pycharm是一个基于python的非常好用的集成开发环境,而python有许多非常不错的开源第三方库,这就需要将一些这样的第三方库导入到我们的项目中去了.然而, ...
- (八十)c#Winform自定义控件-分割线标签-HZHControls
官网 http://www.hzhcontrols.com 前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kww ...
- 数据库查询性能 LinqDB vs Sql查询
使用LinqDB查询Sqlite数据库数据,不管是大数据还是少量的数据,感觉特别耗时,尤其是首次查询 一个含有2.7万条数据的数据表 首次查询: 查询2.7万条数据,耗时1s 查询指定的1条数据,也要 ...