zoukankan      html  css  js  c++  java
  • 基于redis实现分布式锁

    背景

    一套代码部署在四个服务器上,代码逻辑是:检查当前表的总数据条数,满足一定条件后切换到下一个分表

    四个同时都去切换表 + 1 的操作是不可以的,他们要先从 redis 获取一把锁,没有获取到锁的就直接退出,等待下一次定时任务的调度。拿到了锁的就去执行切换当前分表的操作

    实现

    获取锁 和 释放锁 的关键代码如下所示:

    /**
         * Set the string value as value of the key. The string can't be longer than 1073741824 bytes (1
         * GB).
         * @param key
         * @param value
         * @param nxxx NX|XX, NX -- Only set the key if it does not already exist. XX -- Only set the key
         *          if it already exist.
         * @param expx EX|PX, expire time units: EX = seconds; PX = milliseconds
         * @param time expire time in the units of <code>expx</code>
         * @return Status code reply
         * @auther daleyzou
         */
        public boolean set(String key, String value, String nxxx, String expx,
                long time) {
            Jedis jedis = jedisPool.getResource();
            try {
                String result = jedis.set(key, value, nxxx, expx, time);
                if (!StringUtils.isNullOrEmpty(result) && "OK".equals(result)){
                    return true;
                }else {
                    return false;
                }
            } catch (Exception e) {
                dealWithJedisException(e);
            } finally {
                closeJedis(jedis);
            }
            return false;
        }
    
        /***
         * @Description: 解锁时比较值是否相等
         * @date: 22:33 2019/7/22
         * @param: key
         * @param: request value
         * @return: boolean
         */
        public  boolean unlock(String key,String request){
            Jedis jedis = jedisPool.getResource();
            try {
                String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
                Object result = jedis.eval(script, Collections.singletonList(key), Collections.singletonList(request));
    
                Long UNLOCK_SUCCESS = 1L;
                if (UNLOCK_SUCCESS.equals(result)){
                    return true;
                }else {
                    return false;
                }
            } catch (Exception e) {
                dealWithJedisException(e);
            } finally {
                closeJedis(jedis);
            }
            return false;
        }
    

    调用

    private static final String SET_IF_NOT_EXIST = "NX";
    private static final String SET_WITH_EXPIRE_TIME = "EX";
    
    if (myJedisService.set(refreshMaxId, value, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime)){
        // 执行并发的相关操作
        。。。
        myJedisService.unlock(refreshMaxId, value);
        return;
    }else {
        return;
    }
    

    参考

    参考链接:https://crossoverjie.top/2018/03/29/distributed-lock/distributed-lock-redis/

  • 相关阅读:
    照到抄的。C# 多线程自己写的包装器
    转的一份代码应该是 max的吧..
    WPF 里面的 Run .感觉这名称真没取好,application 里面有个 run, textblock 里面也有个.
    Marshal C#
    VS2010推荐实用插件
    Aga.Controls.Tree.TreeViewAdv使用教程之概要介绍
    文档批量下载器
    有趣,http请求接收网站
    Dictionary, KeayValuePair,HashMap,HashTable,待学补充
    kafka和zookeeper的安装
  • 原文地址:https://www.cnblogs.com/daleyzou/p/concurrentLock.html
Copyright © 2011-2022 走看看