面试官扎心一问:防止重复请求提交,有什么方案?

开发 前端
在平常开发中,我们经常会面对防止重复请求的问题。当服务端对于请求的响应涉及数据的修改,或状态的变更时,可能会造成极大的危害。

[[383998]]

 本文转载自微信公众号「UP技术控」,作者 conan5566。转载本文请联系UP技术控公众号。 conan5566  

背景

在平常开发中,我们经常会面对防止重复请求的问题。当服务端对于请求的响应涉及数据的修改,或状态的变更时,可能会造成极大的危害。重复请求的后果在交易系统、售后维权,以及支付系统中尤其严重。但是很多时候,都是指望着前端来限制,比如提交之后,按钮diseabled之类的,其实这些都是不靠谱的。关键时候还是需要后端来校验。

解决方式

1、基于缓存数据状态的验证

Redis存储查询轻量快速。在request进来的时候,可以先记录在缓存中。后续进来的request每次进行验证。整个流程处理完成,清除缓存。

  1. if (!CacheExtension.getInstance().AddUnique($"{key}_unique", 1, DateTimeOffset.Now.AddDays(365))) 
  2.             { 
  3.                 LogExtention.getInstance().WriteCustomLogAsync(""""true"上批次还未执行结束"); 
  4.                 return ResponseResult.FromError("上批次还未执行结束!"); 
  5.             } 
  1. if (!string.IsNullOrEmpty(uniqueKey)) 
  2.             { 
  3.                 CacheExtension.getInstance().Remove(uniqueKey); 
  4.             } 
  5.             return ResponseResult.Ok(); 

2、利用唯一索引机制的验证

需要原子性操作,想到了数据库的唯一索引。新建一个表,每次request进来则往表里面插入数据, 操作完成后,删除此条记录。

3、基于缓存的计数器验证

由于数据库的操作比较消耗性能,了解到redis的计数器也是原子性操作。果断采用计数器。既可以提高性能,还不用存储,而且能提升qps的峰值。 每次request进来则新建一个以orderId为key的计数器,然后+1。如果>1(不能获得锁): 说明有操作在进行,删除。如果=1(获得锁): 可以操作。

  1. redis> SET test 20 
  2. OK 
  3. redis> INCR test 
  4. (integer) 21 
  5. redis> GET test # 数字值在 Redis 中以字符串的形式保存 
  6. "21" 
  7.  
  8. //获取指定的所有计数器 
  9. HGETALL counter:user:{userID}    
  10.  
  11. //获取指定的指定计数器 
  12. HMGET counter:user:{userID}  praiseCnt hostCnt  
  13.  
  14. //指定点赞数+1 
  15. HINCRBY counter:user:{userID}   praiseCnt 

总结

1、c#本身有lock机制,单体模式可以使用。

2、但是考虑到我们的分布式部署,建议还是用缓存。在大并发的情况下,程序各种情况的发生。特别是涉及到金额操作。所以在大并发要互斥的情况下可以考虑2、3两种方案。

 

责任编辑:武晓燕 来源: UP技术控
相关推荐

2020-10-21 18:42:39

数据库数据库查询分页查询

2019-01-29 19:24:06

分库分表数据库

2020-06-22 07:47:46

提交面试官订单

2010-08-23 15:06:52

发问

2023-02-09 07:01:35

转发重定向Java

2022-01-05 09:55:26

asynawait前端

2023-12-05 09:33:08

分布式事务

2023-06-05 07:57:53

Kafka消息事务消息

2021-12-25 22:31:10

MarkWord面试synchronize

2021-11-08 09:18:01

CAS面试场景

2024-03-08 07:53:19

LockMonitor线程

2021-05-27 05:37:10

HTTP请求头浏览器

2024-01-11 08:12:20

重量级监视器

2021-12-16 18:38:13

面试Synchronize

2021-01-06 05:36:25

拉链表数仓数据

2021-07-06 07:27:45

React元素属性

2023-02-17 08:10:24

2021-12-20 10:30:33

forforEach前端

2024-09-09 08:30:56

代码

2021-12-10 12:01:37

finalfinallyfinalize
点赞
收藏

51CTO技术栈公众号