• redis实现分布式锁来防止重复提交问题(redis锁)


    1、何为重复提交
    重复提交是在第一次请求已经在进行处理或处理成功的情况下,人为的进行多次操作,导致不满足幂等要求的服务多次改变状态。

    2、何为幂等
    幂等是其任意多次执行所产生的影响均与一次执行的影响相同(不用担心重复执行会对系统造成改变)。

    3、何时使用

    场景一:在网络延迟的情况下让用户有时间点击多次submit按钮导致表单重复提交

    场景二:表单提交后用户点击【刷新】按钮导致表单重复提交

    场景三:用户提交表单后,点击浏览器的【后退】按钮回退到表单页面后进行再次提交

    4、造成影响

     因为接口重复提交,会造成脏数据,进而导致数据被覆盖或有多笔业务数据问题。

    5、实现思路

    这里我们用到Redis的SET命令

    set(key,value,"NX","EX",expireTime);
    //NX:表示如果key不存在,则设置key-value,否则返回null。
    //EX:过期时间的单位/秒。

    首先找到防止重复提交的标识信息,把参数组装好,这里可以使用MD5加密key,这样重复提交的请求生成的key就是一样的。请求前先获取锁,

    请求结束后必须释放锁,同时我们设置锁的过期时间,可以有效防止死锁。

    6、实现代码

    //获取分布式锁
    public synchronized boolean getRedisLock(String lockKey,String value,long expireTime){
    
    String result=jedisCluster.set(lockKey,value,"NX","EX",expireTime);//单位秒
    if("OK".equalsIgnoreCase(result)){
    return true;
    }else{
    return false;
    }
    }
    
    //释放分布式锁
    public boolean releaseRedisLock(String lockKey,String value){
    String script="if redis.call('get',KEYS[1])==ARGV[1] then redis.call('del',KEYS[1]) else return 0 end";
    String result=jedisCluster.eval(script,Collections.singletonList(lockKey),Collections.singletonList(value));
    if(1L==(Long)result){
    return true;
    }else{
    return false;
    }
    }
    
    //使用分布式锁
    
    String key="xxx";
    String value="xxx";
    boolean lock=getRedisLock(key,value,2*60);//默认两分钟 
    try{
    if(lock){
    //数据保存逻辑
    }else{
    //重复提交提示
    }
    }
    catch(Exception e){
    }finally{
    releaseRedisLock(key,value);//释放锁
    }
  • 相关阅读:
    UVA1585
    暑期第二场-1
    UVA11582
    UVA10006
    HDU1005
    HDU2035
    POJ:2492-Bug's Life(二分图的判定)
    Codeforces:68A-Irrational problem(暴力大法好)
    Codeforces Round #456 (Div. 2) B. New Year's Eve
    Codeforces Round #456 (Div. 2) A. Tricky Alchemy
  • 原文地址:https://www.cnblogs.com/e-x-c-e-ption/p/14863328.html
Copyright © 2020-2023  润新知