Redis-based distributed locks (Java implementation)

Source: Internet
Author: User
Tags uuid
GitHub Source:

Github.com/z521598/redis-lock

Implementation principle:

1.setnx

Redis's setnx Directive (document reference), setnx means set if not eXists, command format: setnx $key $value

If this key does not exist, it is set to value, the return value is 1, and if this key exists, it is not set and the return value is 0. Such as:

127.0. 0.1:6379[1]>1127.0. 0.1:6379[1]>0

Redis is single-threaded and thread-safe, and the setnx instruction is able to meet the demand for locks in high concurrency situations because of the above features.

2.springdata-redis

Springdata-redis is a template method that sends commands to REDIS and accepts data in a high-level abstraction, simply understood as "sending commands to Redis using Java and receiving data from clients" (document reference)

Configuration file: Github.com/z521598/redis-lock/blob/master/src/main/resources/applicationcontext.xml

V1 Description:

The simplest of the most coarse lock implementations, implementing 2 methods.

Method 1: Get the lock, public UUID acquire (String Lockkey, Long acquiretimeoutinmillis, long Lockexpiryinmillis)

Parameter description: Lockkey is the key;acquiretimeoutinmillis of the lock to obtain the wait time for the lock, and if the lock is discarded over this time, the Lockexpiryinmillis is the expiration time of the lock.

Return value: The value of the lock corresponding to "Setnx key value" in the command.

Ideas:

1. Call Springdata-redis's Setifabsent (Lockkey, Value) method (that is, setnx in the command line), value is a random uuid.

2. If true, indicates that the lock has been acquired, continue setting the time-out, and return the set UUID.

If False is returned, then the lock is not acquired, then hibernation is 100ms, and the total sleep time is recorded, if Lockexpiryinmillis is greater than or equal to the time the total sleep is recorded, the lock is not acquired, and Null is returned.

Method 2: Release the lock, public void release (String lockkey, uuid uuid)

Parameter description: Lockkey is the key;uuid of the lock as the value of the lock.

Idea: Check if the value of the lock is a UUID, if it is equal, then release, if not equal, do nothing; prevents the release of locks acquired by other threads.

The obvious disadvantages:

The first step is to get the lock, the second step, and then set the time-out. This is a 2-step operation, not an atomic operation, if after the first step, the program crashes or power down or redis happens to be a master-slave switch, and so on, the second step can not be performed properly, so that the lock will never be released.

Code:
 PublicUUID Acquire (String Lockkey,LongAcquiretimeoutinmillis,LongLockexpiryinmillis)throwsinterruptedexception {uuid uuid=Uuid.randomuuid (); LongTimeout = 0L;  while(Timeout <Acquiretimeoutinmillis) {            if(Redistemplate.opsforvalue (). Setifabsent (Lockkey, uuid.tostring ())) {Redistemplate.expire (Lockkey, Lockexpiryinmillis, timeunit.milliseconds); returnuuid;            } TimeUnit.MILLISECONDS.sleep (Default_acquire_resolution_millis); Timeout+=Default_acquire_resolution_millis; }        return NULL; }

Lock implementation: Github.com/z521598/redis-lock/blob/master/src/main/java/com/redis/lock/sdata/v1/lockservice.java

Unit Test: Github.com/z521598/redis-lock/blob/master/src/test/java/com/redis/lock/sdata/v1/lockservicetest.java

V2 Description:

Roughly the same as V1, but the value of the lock is "expired", and if the lock is acquired, the expiration time is less than now, then the lock is considered to have expired.

Cons: (Rare occurrences)

When Redis is a master-slave form, after acquiring the lock, Master goes down, slave takes over, but this time the "new master" has not yet synchronized the lock key. At this point, the other thread acquires the lock, finds that there is no key, and acquires a lock that should not be acquired, which can cause an unsafe situation.

Code:

Lock implementation: GITHUB.COM/Z521598/REDIS-LOCK/TREE/MASTER/SRC/MAIN/JAVA/COM/REDIS/LOCK/SDATA/V2

Unit Test: Github.com/z521598/redis-lock/blob/master/src/test/java/com/redis/lock/sdata/v2/lockv2servicetest.java

V3

Please expect

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.