首页 > 其他分享 >防止接口重复调用方法

防止接口重复调用方法

时间:2023-11-30 15:56:40浏览次数:28  
标签:调用 重复 Redis 接口 保证 线程 lockKey

1、使用数据库唯一索引:

为需要防重复的字段添加唯一索引,再尝试插入,如果重复会报错。

2、使用线程本地变量

利用ThreadLocal存储是否调用过的标识变量。

private static final ThreadLocal<Bolean> CALLED =new ThreadLocal<>();
if(CALLED.get() != null) {
  //已调用
} else {
  CALLED.set(true);
  //调用逻辑
}

3、使用synchronized同步块

private static final Object LOCK = new Object();
synchronized(LOCK) {
  if(isCalled) {
  //已调用  
  } else {
  isCalled = true;
  //调用逻辑
  }
}

4、使用AQS同步器实现锁

ReentrantLock、ReentrantReadWriteLock等。

5、使用全局变量加volatile

保证可见性,但不保证原子性。

6、使用数据库sequence生成唯一ID

避免业务重复调用。

7、redis锁。

防止重复调用的原理如下:

1、Redis锁

利用Redis的SETNX命令可以实现原子锁,保证同一时刻只有一个客户端能获取锁,其他客户端获取锁失败。通过设置过期时间实现锁的自动释放。

数据库唯一索引

为需要保证唯一的字段添加唯一索引约束。如果重复插入会报错,从而保证不重复执行业务逻辑。

2、ThreadLocal

ThreadLocal利用线程局部变量存储是否调用过的标记。由于每个线程都有自己的副本,可以保证同一线程内不重复调用。

3、同步锁

synchronized通过监视器对象(锁)实现同步,保证同一时刻只有一个线程持有锁执行同步代码块。其他线程获取锁失败被阻塞。

4、全局变量

利用volatile修饰全局变量,保证变量在不同线程之间的可见性。但不保证原子性,可能还是存在重复调用的风险。

5、序列号

使用数据库序列生成全局唯一的ID,保证业务执行时使用的ID不重复,从而避免重复调用。

总之,这些方法通过加锁、唯一约束等手段,都可以保证同一时刻只有一个线程/客户端执行需要防重复的业务逻辑,从而达到防重复调用的目的。

使用Redis的setkey和getkey方法防止重复调用有一定的问题:

1、setkey和getkey操作不是原子性的,存在竞争条件。多个线程同时调用setkey设置值,那么getkey可能拿到旧值,导致重复调用。

2、getkey只能判断值是否存在,无法实现锁功能。无法保证同一时刻只有一个线程执行业务逻辑。

3、没有设置key的过期时间,key会永久存在Redis中,不利于资源回收。

所以使用setkey和getkey防止重复调用存在以下潜在问题:

1、可能导致重复调用,无法保证原子性。

2、无法实现锁功能,无法保证同时只有一个线程执行。

3、key资源无法自动回收,可能会长期占用Redis存储空间。

相比之下,使用Redis的SETNX命令实现锁功能会更可靠一些:

1、SETNX是原子操作,可以保证同时只有一个客户端获取锁成功。

2、可以设置key的过期时间,锁资源可以自动释放。

3、锁可以实现同步控制,保证同时只有一个线程执行业务逻辑。

所以,如果要使用Redis防止重复调用,推荐使用SETNX实现分布式锁,而不是直接使用setkey和getkey。这可以更好地保证原子性和同步控制。

业务层代码:
//分布式锁key String lockKey = ""; //防重复提交(通过Redis的setIfAbsent实现了分布式锁) if (!redisUtil.tryGetDistributeLock(lockKey, 2)) { //释放锁 redisUtil.releaseDistributeLock(lockKey); // 锁获取失败,直接返回 return new BaseModel(HttpUtil.failCode, "您的操作过于频繁,请稍后再试!", null); } Try{ }catch(){ }finally{ //释放锁 redisUtil.releaseDistributeLock(lockKey); }
redisutil: 
//获取锁 public Boolean tryGetDistributeLock(String lockKey, int timeout) { return redisTemplate.opsForValue().setIfAbsent(lockKey, "1", timeout, TimeUnit.SECONDS); } //释放锁 public void releaseDistributeLock(String lockKey) { redisTemplate.delete(lockKey); }

 

标签:调用,重复,Redis,接口,保证,线程,lockKey
From: https://www.cnblogs.com/wmy666/p/17867535.html

相关文章

  • 83. 删除排序链表中的重复元素
    83.删除排序链表中的重复元素2021年3月26日删除排序链表中的重复元素II的简化版,while套while就行为了时间,指针都不删除吗?classSolution{public:ListNode*deleteDuplicates(ListNode*head){ListNode*p=head;while(p&&p->next){w......
  • 在web-view加载的本地及远程HTML中调用uni的API及网页和vue页面通讯
    转载于在web-view加载的本地及远程HTML中调用uni的API及网页和vue页面通讯-DCloud问答uni-app的web-view组件,支持加载远程网页,在app环境下,还支持加载本地HTML页面。在web-view加载页面中,会涉及wx、plus、uni等对象的使用。在小程序下使用wx的api,需要引入微信提供的https......
  • 调用BarTender打印标签
    1privateBarTender.ApplicationbtAPP;2privateBarTender.FormatbtFormat;3//初始化对象4btAPP=newBarTender.Application();56try7{8btFormat=btApp.Form......
  • go数据类型-空结构体、空接口、nil
    空结构体funcmain(){ a:=struct{}{} fmt.Println(unsafe.Sizeof(a)) fmt.Printf("%p\n",&a)}打印00x117f4e0有经验的开发人员都知道,所有的空结构体是指向一个zerobase的地址,而且大小为0一般用来作结合map作为set或者在channel中传递信号。t......
  • Java集合框架主要接口及实现类详解
    Java集合框架是Java编程语言提供的一组接口,用于处理对象集合。Java集合框架中包括了一系列的接口、实现类和算法,可以方便地操作和管理各种类型的集合数据。Java集合框架主要包括以下接口:Collection接口:是所有集合接口的根接口,提供了基本的集合操作,如添加、删除、遍历等操作。L......
  • 接口请求重复调用,只保留最后一个请求的返回结果
    在前端开发中,有时候我们需要确保即使发起了多次相同的请求,也只处理最后一次请求的响应。这种需求在搜索输入提示、自动完成或者连续的数据更新操作中比较常见。为了实现这个功能,我们可以使用取消之前请求的策略,或者通过标记的方式来确保只处理最后一次请求的结果。以下是使用Java......
  • 绑定给类的方法,对象来调用;与绑定给对象的方法,类来调用的区别
    绑定给类的方法,类来调用,对象可以调用吗?#首先创建一个类,和绑定给类的方法indexclassMyClass:@classmethoddefindex(cls):print("helloindex")实例化对象:obj=MyClass()使用对象调用绑定给类的方法:obj.index()#返回hello......
  • 将1234数字,组成不重复的3数字组合,并统计组合个数
    total=0forainrange(1,5):forbinrange(1,5):forcinrange(1,5):ifa!=banda!=candb!=c:total=total+1print(a,b,c)print(total) ......
  • 秦疆的Java课程笔记:46 方法 方法的定义和调用
    Java方法类似于其他语言的函数,是一段用来完成特定功能的代码片段,一般情况下,定义一个方法包含以下语法:修饰符返回值类型方法名(参数类型参数名){//这一串就是方法头 …… 方法体 …… return返回值;}方法包含一个方法头和方法体。下面是一个方法的所有部分:......
  • 接口测试:接口常见bug分类
    一、接口参数数据类型:1.数值型2.字符串类型3.数组或者链表类型4.结构体二、接口测试常见bug:1.特殊值处理不当导致程序异常退出或者崩溃2.类型边界溢出,导致数据读出和写入不一致3.取值边界外值未返回正确的错误信息4.参数为null或空字符串“”等5.权限未处理,......