Redis implement a simple version of distributed locks

Source: Internet
Author: User
Tags lua redis

Principle:

Gets the specified name key if present, if there is no key, if there is no value assigned to the key, then set the expiration time;

The logic to unlock deletes the key.


1. Custom class

Package com.xxx.cloud.assets.redis.lock;
Import java.util.Collections;
Import Java.util.UUID;

Import Java.util.concurrent.TimeUnit;
Import Org.springframework.data.redis.core.RedisTemplate;

Import Org.springframework.data.redis.core.script.DefaultRedisScript; 

    /** * Each time you use, to new lock use/public class Redislock {//Lock name private String lockname;

    Lock timeout private long time;

    private static final String Key_prefix = "Businessname:lock:";

    Private long Randomvalue;

    Private Defaultredisscript Redisscript;

    Private Redistemplate redistemplate;

    Private Boolean locked; Private Redislock (String lockname, long time, Redistemplate redistemplate, Defaultredisscript redisscript) {this.
        Lockname = Key_prefix + lockname;
        This.time = time;
        This.redistemplate = redistemplate;
        This.redisscript = Redisscript;
    This.randomvalue = Uuid.randomuuid (). Getleastsignificantbits (); } public static Redislock NewredisLock (String lockname, Long, redistemplate redistemplate, Defaultredisscript redisscript) {return
    New Redislock (Lockname, Time, Redistemplate, redisscript); public Boolean Trylock () {Boolean success = Redistemplate.opsforvalue (). Setifabsent (Lockname, Randomvalue)
        ;
        Setifabsent corresponding to Redis setnx method locked = success;
        if (success) {Redistemplate.expire (Lockname, Time, timeunit.seconds);
    return success; public void UnLock () {if (locked) {Redistemplate.execute (Redisscript, collections.singletonlist
        (Lockname), randomvalue);
 }

    }

}


2. Test code

Package com.xxx.cloud.assets.service;
Import Com.xxx.cloud.assets.redis.lock.RedisLock;
Import Com.xxx.cloud.assets.test.TestBase;
Import Org.junit.Test;
Import Org.springframework.data.redis.core.RedisTemplate;

Import Org.springframework.data.redis.core.script.DefaultRedisScript;
Import Javax.annotation.Resource;
Import Java.util.concurrent.ExecutorService;
Import java.util.concurrent.Executors;

Import Java.util.concurrent.TimeUnit; public class Testredislock extends Testbase {@Resource (name = "Redistemplate") Private redistemplate Redistempla

    Te

    @Resource (name = "Dellockscript") private defaultredisscript dellockscript; @Test public void Testredislock () throws Interruptedexception {Redislock lock = Redislock.newredislock ("Test"
        , 1000,redistemplate,dellockscript);
            try {Boolean success = Lock.trylock ();
        SYSTEM.OUT.PRINTLN (Success);
        }finally {lock.unlock (); }} @Test Publicvoid Testmulredislock () throws interruptedexception {final Redislock lock1 = Redislock.newredislock ("Test", 1000,r
        Edistemplate,dellockscript);
        Final Redislock Lock2 = Redislock.newredislock ("Test", 1000,redistemplate,dellockscript); Runnable Task1 = new Runnable () {@Override public void run () {try {bool
                    EAN success = Lock1.trylock ();
                    System.out.println ("Task1" + success);
                TimeUnit.SECONDS.sleep (10);
                }catch (Exception e) {e.printstacktrace ();
                finally {Lock1.unlock ();

        }
            }
        }; Runnable task2 = new Runnable () {@Override public void run () {try {bool
                    EAN success = Lock2.trylock ();
                    System.out.println ("Task2" +success);
               TimeUnit.SECONDS.sleep (10); }catch (Exception e) {e.printstacktrace ();
                finally {Lock2.unlock ();

        }
            }
        };
        Executorservice Executorservice = Executors.newcachedthreadpool ();
        Executorservice.submit (TASK1);
        Executorservice.submit (TASK2);
    TimeUnit.SECONDS.sleep (15);
 }
}

3.spring part of the configuration

<bean id= "Redistemplate" class= "org.springframework.data.redis.core.RedisTemplate" >
		<property name= " ConnectionFactory "ref=" jedisconnectionfactory "/>
		<property name=" Defaultserializer ">
			<bean class= "Org.springframework.data.redis.serializer.StringRedisSerializer"/>
		</property>
</ bean>

<bean id= "Dellockscript" class= "Org.springframework.data.redis.core.script.DefaultRedisScript" >
		<property name= "Location" value= "Classpath:database/dellock.lua"/> <property name=
		" Resulttype "value=" Java.lang.Boolean "/>
</bean>

4.dellock.lua script (can also be replaced with code logic)

If Redis.call ("Get", keys[1]) = = Argv[1] then return
	redis.call ("Del", Keys[1])
else return
	0





Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.