当前位置:网站首页>Several implementation methods of redis distributed lock

Several implementation methods of redis distributed lock

2022-06-09 05:30:00 CodingAnHour

1、Jedis

    /** *  Acquire distributed lock , Lock ID returned successfully  * @param lockName  Compete to acquire locks key * @param acquireTimeoutInMS  Gets the locktimeout time  * @param lockTimeOut  The timeout of the lock ( second ) * @return  Lock logo  */
    public String acquireLockWithTimeout(String lockName, long acquireTimeoutInMS, int lockTimeOut) {
    
        Jedis conn = null;

        //  Lock logo 
        String retIdentifier = null;
        try {
    
            conn = jedisPool.getResource();
            //  Value of lock 
            String identifier = UUID.randomUUID().toString();
			//  The lock key
            String lockKey = "lock:" + lockName;

            //  Gets the locktimeout time 
            long end = System.currentTimeMillis() + acquireTimeoutInMS;

            while (System.currentTimeMillis() < end) {
    
                // key In the presence of , Do not operate , return 0, A situation that does not exist set identifier  return 1
                if (conn.setnx(lockKey, identifier) == 1) {
    
                    //  Set up  lockKey  Time to live , When  lockKey  expires , It will be automatically deleted 
                    conn.expire(lockKey, lockTimeOut);
                    //  Returns the lock identifier 
                    retIdentifier = identifier;
                    //  Get the lock and jump out of the loop , return 
                    break;
                }

                try {
    
                	//  Rotation sleep 10 millisecond 
                    Thread.sleep(10);
                } catch (InterruptedException ie) {
    
                    Thread.currentThread().interrupt();
                }
            }
        } finally {
    
            if (conn != null) {
    
                conn.close();
            }
        }
        return retIdentifier;
    }


    /** *  Acquire distributed lock , If successful, the lock ID will be returned , Failure return null  * @param lockName  Compete to acquire locks key * @param lockTimeOut  The timeout of the lock ( second ) * @return  Lock logo  */
    public String acquireLock(String lockName, int lockTimeOut) {
    
        Jedis conn = null;

        //  Lock logo 
        String retIdentifier = null;
        try {
    
            conn = jedisPool.getResource();
            String identifier = UUID.randomUUID().toString();

            String lockKey = "lock:" + lockName;

            // key In the presence of , Do not operate , return 0, A situation that does not exist set identifier  return 1
            if (conn.setnx(lockKey, identifier) == 1) {
    
                //  Set up  lockKey  Time to live , When  lockKey  expires , It will be automatically deleted 
                conn.expire(lockKey, lockTimeOut);
                //  Returns the lock identifier 
                retIdentifier = identifier;
                //  Get the lock and jump out of the loop , return 
            }

        } finally {
    
            if (conn != null) {
    
                conn.close();
            }
        }
        return retIdentifier;
    }

    /** *  Release the lock  * @param lockName  Compete to acquire locks key * @param identifier  Release lock identification  * @return */
    public boolean releaseLock(String lockName, String identifier) {
    
        Jedis conn = null;
        //  lock key
        String lockKey = "lock:" + lockName;
        //  Return to status 
        boolean retFlag = false;
        try {
    
            conn = jedisPool.getResource();
            while (true) {
    
                //  monitor lock, If before the transaction is executed ( Or these ) key  Altered by other orders , Then the business will be interrupted .
                conn.watch(lockKey);
                if (identifier.equals(conn.get(lockKey))) {
    
                    // Open transaction 
                    Transaction trans = conn.multi();
                    //  Delete key
                    trans.del(lockKey);
                    //  Execute commands within all transaction blocks  EXEC  Command atomicity 
                    List<Object> results = trans.exec();
                    if (results == null) {
    
                        continue;
                    }
                    retFlag = true;
                }
                //  Cancel  WATCH  Command to all  key  Surveillance 
                conn.unwatch();
                break;
            }

        } finally {
    
            if (conn != null) {
    
                conn.close();
            }
        }
        return retFlag;
    }

2、RedisTemplate


	/** *  Atomic insertion ( Mutually exclusive ), Successfully returns true * @param key * @param value * @param timeout-seconds * @return */
	public boolean setNX(String key,String value,int timeout) {
    
    	return redisTemplate.opsForValue().setIfAbsent(key, value,timeout,TimeUnit.SECONDS);
    }

3、Redission

<!--  Distributed redis lock  -->
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.6.5</version>
</dependency>

Inject bean, For reference only , The parameters in the environment can be matched more gracefully

    @Bean
    public RedissonClient redisson(){
    
        //  standalone mode 
        Config config = new Config();
        config.useSingleServer().setAddress("redis://127.0.0.1:6380").setDatabase(1);
        return Redisson.create(config);
    }

java Example

@RequestMapping(value = "/stock")
    public String deductStock(){
    
        //  Encrypted key
        String lockKey = "product:001";
        // 1. Get lock object 
        RLock redissonLock = redisson.getLock(lockKey);
        try{
    
            // 2. Lock   Equivalent to  setIfAbsent, Default key Expiration time 30s
            redissonLock.lock();
            //  from redis  Get the value of the current inventory 
            int stock = Integer.parseInt(redisUtil.get("stock"));
            if(stock > 0){
    
                int realStock = stock - 1;
                boolean stock1 = redisUtil.set("stock", realStock+"");
                System.out.println(" Deduction succeeded , Surplus stock :" + realStock);
            }else{
    
                System.out.println(" Deduction failed , Insufficient inventory ");
            }
        }finally {
    
            // 3. Release the lock 
            redissonLock.unlock();
        }
        return"end";
    }

Redission The middle lock bottom layer uses lua It is implemented by script

  1. exists Judge key Whether there is
  2. When it is judged that there is no such thing as hash How to set key
  3. Then set the key Add expiration time
  4. Evoke a scheduled task running in the background , Every time the lock expiration time is set 1/3 Time to execute once , Delay the lock

 Insert picture description here
 Insert picture description here
The same goes for releasing the lock lua How to script
 Insert picture description here

4、 Distributed locking techniques

scene 1:

  • When redis When a single commodity or multiple commodities are snapped up (redis Cluster structure ), Commodity distributed lock definition key=product:001 when , Locks occupy all nodes , If key=product:001-100:001;key=product:101-200:101 To disperse the lock , In this way, locking can make the lock fall on different nodes , Make full use of cluster multi node mode , Realize the horizontal expansion of the lock , Improve lock performance
原网站

版权声明
本文为[CodingAnHour]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/160/202206090517500565.html