Spring boot redis [] [] spring boot implement distributed lock LUA script based on the redis

spring boot implement distributed lock LUA script based on the redis [it is] based on a single point at redis

 

.Spring boot 1.5.X achieve a distributed lock lua script based on the redis

1.pom.xml

<!-- Redis -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

 

2.RedisLock tools (Spring injection)

Import org.springframework.beans.factory.annotation.Autowired;
 Import org.springframework.data.redis.core.RedisTemplate;
 Import org.springframework.data.redis.core.script.DefaultRedisScript;
 Import org.springframework.data.redis. core.script.RedisScript;
 Import org.springframework.data.redis.serializer.StringRedisSerializer;
 Import org.springframework.stereotype.Component;
 Import java.util.Collections; 


/ ** 
 * the Spring the Boot 1.5.X 
 * redis use of lua script based on single-point implementation of distributed lock 
 * 
 * Lua script as an atomic operation, and to ensure the lock timeout setting atomic operations 
 * @author SXD 
 * @date 2019/5/27 10:52 
 * /
@Component 
public  class RedisLock { 

    @Autowired 
    RedisTemplate redisTemplate; 

    Private  static  Final Long 1L = SUCCESS ; 

    / ** 
     * Get lock 
     * 
     * @param lockKey Redis of Key 
     * @param value is required value redis random string, preventing the release of other requests lock 
     * @param expiration time of expireTime redis key to prevent a deadlock that causes other requests can not perform normal operations 
     * @return 
     * / 
    public   boolean lock (lockKey String, String value, int expireTime) { 

        String Script= "if redis.call('setNx',KEYS[1],ARGV[1])  then " +
                "   if redis.call('get',KEYS[1])==ARGV[1] then " +
                "      return redis.call('expire',KEYS[1],ARGV[2]) " +
                "   else " +
                "      return 0 " +
                "   end " +
                "end";

        RedisScript<String> redisScript = new DefaultRedisScript<>(script, String.class);

        //对非string类型的序列化
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        Result Object=redisTemplate.execute (redisScript, Collections.singletonList (lockKey), value, String.valueOf (expireTime)); 

        return SUCCESS.equals (Result); 

    } 

    / ** 
     * lock release 
     * 
     * @param lockKey Redis of Key 
     * @param value redis only the value of the same ratio value, to determine that the present request is added to the normal release latch 
     * @return 
     * / 
    public   Boolean UNLOCK (lockKey String, String value) { 

        String Script = "IF redis.call ( 'GET', KEYS [. 1]) == ARGV [. 1] redis.call the then return ( 'del', KEYS [. 1]) End the else return 0 " ; 

        redisScript <String> = redisScript new new DefaultRedisScript<>(script, String.class);

        try {
            Object result = redisTemplate.execute(redisScript, Collections.singletonList(lockKey), value);
            if (SUCCESS.equals(result)) {
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

}
View Code

 

3.controller use

/ ** 
     * Use the Distributed Lock logic 
     * 1. Prepare the value expireTime Key 
     * value is required random string 
     * expireTime lock expiration date is based on a measure of business decisions 
     * 
     * 2. Get lock 
     * successful acquisition, the implementation of business execution complete, release the lock 
     * failure to obtain, retry acquisition, pay attention to the time interval to acquire the lock until the acquisition is successful, the implementation of the business, and finally release the lock 
     * 
     * Note: 
     * for redis locked business, try to use in a short time-consuming business on. 
     * 
     * / 
    @RequestMapping ( "/ Test" )
     public  void Test () {
         Boolean In Flag = to false ; // identifier to acquire the lock is normal 
        String UUID = UUID.randomUUID () toString ();. // Redis value is a string of random number
        = Lock.lock In Flag ( "mykey1", UUID,. 5 );
         IF (In Flag) { 
            Business (UUID); 
        } the else { 

            // If the lock is not acquired by the normal acquire a retry until successful lock 
            the while (! In Flag) {
                 the try { 

                    // retry interval to reduce the number of interactions with redis 
                    the Thread.sleep (3000 ); 
                    System.out.println ( "retry" ); 
                    In Flag = Lock.lock ( "mykey1", UUID,. 5 );
                     IF (In Flag) { 
                        Business (UUID); 
                    } the else {
                        Continue ; 
                    } 

                } the catch (InterruptedException E) { 
                    e.printStackTrace (); 
                } 

            } 
        } 
    } 

    public  void Business (UUID String) { 
        
        the try { 
            System.out.println ( "lock successful implementation of business" ); 
            the Thread.sleep ( 10000 ); 
        } the catch (InterruptedException E) { 
            e.printStackTrace (); 
        } the finally {
             // service execution is completed normally releasing the lock 
            lock.unlock ( "mykey1",uuid);
        }
    }
View Code

 

 

 

Two .spring boot 2.x implementation of distributed lock LUA script based on the redis

1.

 

Guess you like

Origin www.cnblogs.com/sxdcgaq8080/p/10931246.html