广告
返回顶部
首页 > 资讯 > 后端开发 > Python >redis分布式锁解决表单重复提交的问题
  • 106
分享到

redis分布式锁解决表单重复提交的问题

2024-04-02 19:04:59 106人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

假如用户的网速慢,用户点击提交按钮,却因为网速慢,而没有跳转到新的页面,这时的用户会再次点击提交按钮,举个例子:用户点击订单页面,当点击提交按钮的时候,也许因为网速的原因,没有跳转到

假如用户的网速慢,用户点击提交按钮,却因为网速慢,而没有跳转到新的页面,这时的用户会再次点击提交按钮,举个例子:用户点击订单页面,当点击提交按钮的时候,也许因为网速的原因,没有跳转到新的页面,这时的用户会再次点击提交按钮,如果没有经过处理的话,这时用户就会生成两份订单,类似于这种场景都叫重复提交。

使用redis的setnx和getset命令解决表单重复提交的问题。

1.引入Redis依赖和aop依赖


		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-redis</artifactId>
            <version>1.3.8.RELEASE</version>
        </dependency>

		<dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

2.编写加和解锁的方法。



@Component
public class RedisLock {

    private final Logger logger = LoggerFactory.getLogger(RedisLock.class);

    @Autowired
    private StringRedisTemplate redisTemplate;

    
    public boolean lock(String key,String value){
        //加锁成功返回true
        if(redisTemplate.opsForValue().setIfAbsent(key,value,10, TimeUnit.SECONDS)){
            return true;
        }
        String currentValue = redisTemplate.opsForValue().get(key);
        //加锁失败,再判断是否由于解锁失败造成了死锁的情况
        if(StringUtils.isNotEmpty(currentValue) && Long.parseLong(currentValue) < System.currentTimeMillis()){
            //获取上一个锁的时间,并且重新设置锁
            String oldValue = redisTemplate.opsForValue().getAndSet(key, value);
            if(StringUtils.isNotEmpty(oldValue) && oldValue.equals(currentValue)){
                //设置成功,重新设置锁是保证了单线程的运行
                return true;
            }
        }
        return false;
    }

    
    public void unLock(String key,String value){
        try {
            String currentValue = redisTemplate.opsForValue().get(key);
            if(StringUtils.isNotEmpty(currentValue) && currentValue.equals(value)){
                redisTemplate.delete(key);
            }
        }catch (Exception e){
            logger.error("redis分布式锁,解锁异常",e);
        }
    }


    
    public void unLock(String key){
        try {
            String currentValue = redisTemplate.opsForValue().get(key);
            if(StringUtils.isNotEmpty(currentValue)){
                redisTemplate.delete(key);
            }
        }catch (Exception e){
            logger.error("redis分布式锁,解锁异常",e);
        }
    }
}

3.使用拦截器在请求之前进行加锁的判断。


@Configuration
public class LoginInterceptor extends HandlerInterceptorAdapter {
    private final Logger logger = LoggerFactory.getLogger(LoginInterceptor.class);
    //超时时间设置为10秒
    private static final int timeOut = 10000;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private RedisLock redisLock;
    
    @Override
    public boolean preHandle(httpservletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String path = request.getServletPath();
        if (path.matches(Constants.NO_INTERCEPTOR_PATH)) {
            //不需要的拦截直接过
            return true;
        } else {
            // 这写你拦截需要干的事儿,比如取缓存,SESSION,权限判断等
            //判断是否是重复提交的请求
			if(!redisLock.lock(DigestUtils.md5Hex(request.getRequestURI()+value),String.valueOf(System.currentTimeMillis()+timeOut))){
                        logger.info("===========获取锁失败,该请求为重复提交请求");
                        return false;
 			 }
            return true;
        }
    }
}

4.使用aop在后置通知中进行解锁。



@Aspect
@Component
public class RepeatedSubmit {

    @Autowired
    private RedisLock redisLock;

    //定义切点
    @Pointcut("execution(public * com.kunluntop.loGIStics.controller..*.*(..))")
    public void pointcut(){

    }

    //在方法执行完成后释放锁
    @After("pointcut()")
    public void after(){
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        redisLock.unLock(DigestUtils.md5Hex(request.getRequestURI()+ CookieUtils.getCookie(request,"userkey")));
    }
}

到此这篇关于redis分布式锁解决表单重复提交的问题的文章就介绍到这了,更多相关redis 表单重复提交内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: redis分布式锁解决表单重复提交的问题

本文链接: https://www.lsjlt.com/news/158649.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • redis分布式锁解决表单重复提交的问题
    假如用户的网速慢,用户点击提交按钮,却因为网速慢,而没有跳转到新的页面,这时的用户会再次点击提交按钮,举个例子:用户点击订单页面,当点击提交按钮的时候,也许因为网速的原因,没有跳转到...
    99+
    2022-11-12
  • redis分布式锁如何解决表单重复提交的问题
    本篇文章为大家展示了redis分布式锁如何解决表单重复提交的问题,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。假如用户的网速慢,用户点击提交按钮,却因为网速慢,而没有跳转到新的页面,这时的用户会再次...
    99+
    2023-06-21
  • redis表单重复提交问题怎么解决
    解决 Redis 表单重复提交问题可以通过以下几种方式:1. 使用 Redis 的原子性操作:在提交表单时,先通过 Redis 的 ...
    99+
    2023-09-11
    redis
  • 如何解决redis分布式锁的问题
    这篇文章主要为大家展示了“如何解决redis分布式锁的问题”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“如何解决redis分布式锁的问题”这篇文章吧。分布式锁在...
    99+
    2022-10-18
  • 解决python-redis-lock分布式锁的问题
    python-redis-lock 官方文档 不错的博文可参考 问题背景 在使用celery执行我们的异步任务时,为了提高效率,celery可以开启多个进程来启动对应的worke...
    99+
    2022-11-12
  • SpringBoot + Redis怎么解决重复提交问题
    这篇文章主要为大家展示了“SpringBoot + Redis怎么解决重复提交问题”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“SpringBoot + ...
    99+
    2023-06-22
  • Redisson如何解决Redis分布式锁提前释放问题
    目录前言:一、问题描述:二、原因分析:三、解决方案:1、思考: 2、Redisson简单配置:3、使用样例:四、源码分析1、lock加锁操作2、unlock解锁操作总结:相...
    99+
    2022-11-13
  • redis分布式锁释放问题怎么解决
    在Redis中实现分布式锁时,可以使用以下两种方式解决锁释放的问题: 设置锁的过期时间:在获取锁时,设置一个过期时间,超过该时间...
    99+
    2023-10-27
    redis
  • Redis分布式锁解决秒杀超卖问题
    目录分布式锁应用场景单体锁的分类分布式锁核心逻辑分布式锁实现的问题——死锁和解决Redis解决删除别人锁的问题分布式锁应用场景 秒杀环境下:订单服务从库存中心拿到库存数,如果库存总数大于0,则进...
    99+
    2022-07-13
    Redis秒杀超卖 Redis分布式锁
  • 怎么解决python-redis-lock分布式锁的问题
    本篇内容介绍了“怎么解决python-redis-lock分布式锁的问题”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!问题背景在使用cele...
    99+
    2023-06-25
  • SpringBoot + Redis如何解决重复提交问题(幂等)
    目录幂等:解决方案:一、搭建Redis服务二、自定义注解三、Token创建和校验四、拦截器配置五、正常Sevice类六、Controller类七、测试在开发中,一个对外暴露的接口可能...
    99+
    2022-11-12
  • SpringBoot如何使用 Redis 分布式锁解决并发问题
    这期内容当中小编将会给大家带来有关SpringBoot如何使用 Redis 分布式锁解决并发问题,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。问题背景现在的应用程序架构中,很多服务都是多副本运行,从而保证...
    99+
    2023-06-25
  • 关于SpringBoot 使用 Redis 分布式锁解决并发问题
    目录问题背景解决方案主要实现原理: 可靠性: SpringBoot 集成使用 Redis 分布式锁使用示例参考文档问题背景 现在的应用程序架构中,很多服务都是多副本运行,从而保证服务...
    99+
    2022-11-12
  • web开发中图片按钮提交与表单重复提交的问题分析
    这篇文章主要介绍web开发中图片按钮提交与表单重复提交的问题分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!很多情况下为了美化表单都会把提交按钮改成用一个图片来代替。但如果没有注意细节的话会造成表单的重复提交,导致...
    99+
    2023-06-08
  • 详解Redis 分布式锁遇到的序列化问题
    场景描述 最近使用 Redis 遇到了一个类似分布式锁的场景,跟 Redis 实现分布式锁类比一下,就是释放锁失败,也就是缓存删不掉。又踩了一个 Redis 的坑…… 这是什么个情...
    99+
    2022-11-12
  • Redis的setNX分布式锁超时时间失效 -1问题及解决
    目录Redis setNX分布式锁超时时间失效 -1使用SETNX加锁使用 RedisTemplate 操作Redis解决死锁Redis分布式锁,超时问题的处理分布式可能会出现的超时问题总结Redis setNX分布式锁...
    99+
    2023-01-09
    Redis分布式锁 setNX分布式锁超时时间失效 RedissetNX分布式锁超时
  • Redis的setNX分布式锁超时时间失效-1问题及解决
    目录Redis setNX分布式锁超时时间失效 -1使用SETNX加锁使用 RedisTemplate 操作Redis解决死锁Redis分布式锁,超时问题的处理分布式可能会出现的超时...
    99+
    2023-01-09
    Redis分布式锁 setNX分布式锁超时时间失效 Redis setNX分布式锁超时
  • 解决vue表单为空也能提交的问题
    目录vue表单为空也能提交大概是这样写的vue的表单提交方式vue表单收集和提交vue表单为空也能提交 今天在用Vue写表单验证的时候,习惯性把v-model绑定的值设置为null,...
    99+
    2022-11-13
  • 详解RedisTemplate下Redis分布式锁引发的系列问题
          自己的项目因为会一直抓取某些信息,但是本地会和线上经常一起跑,造成冲突。这其实就是我们常说的分布式集群的问题了,本地和线...
    99+
    2022-11-11
  • 使用redis分布式锁解决并发线程资源共享问题
    前言 众所周知, 在多线程中,因为共享全局变量,会导致资源修改结果不一致,所以需要加锁来解决这个问题,保证同一时间只有一个线程对资源进行操作 但是在分布式架构中,我们的服务可能会有n个实例,但线程锁只对同一...
    99+
    2022-10-18
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作