The internet is littered with code for distributed locks, mostly through setnx and expire
These two are not atomic operations, there will certainly be problems, there are many people by using SETNX value as the expiration time to compensate and so on. But it doesn't seem very good, or a little bit of a problem.
Code derived from a great God.
1 PackageCom.abc.def.util;2 3 ImportRedis.clients.jedis.Jedis;4 5 Importjava.util.Collections;6 7 Public classRedisdistributedlock {8 9 Ten Private Static FinalString lock_success = "OK"; One Private Static FinalString set_if_not_exist = "NX"; A Private Static FinalString set_with_expire_time = "PX"; - Private Static FinalLong release_success = 1L; - the /** - * Try to acquire a distributed lock - * @paramJedis Redis Client - * @paramLockkey Lock + * @paramRequestID Request Identification - * @paramExpiretime Extended Time + * @returnwhether to get success A */ at Public Static BooleanTrygetdistributedlock (Jedis Jedis, String Lockkey, String RequestID,intexpiretime) { - -String result =Jedis.set (Lockkey, RequestID, Set_if_not_exist, Set_with_expire_time, expiretime); - - if(lock_success.equals (Result)) { - return true; in } - return false; to + } - the /** * * Release Distributed Locks $ * @paramJedis Redis ClientPanax Notoginseng * @paramLockkey Lock - * @paramRequestID Request Identification the * @returnwhether to release success + */ A Public Static BooleanReleasedistributedlock (Jedis Jedis, String Lockkey, String RequestID) { the +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 (Lockkey), Collections.singletonlist (RequestID)); $ $ if(release_success.equals (Result)) { - return true; - } the return false; - Wuyi } the -}
Gets the lock, which is obtained by a single instruction and sets the timeout at the same time.
In addition, unlocking is the key that is set when the lock is acquired by the key should be a random value is recommended to use the UUID to generate. So you can only unlock your own locks.
Additionally, the Lua script that unlocks the operation is executed, and three statements are assembled into an atomic operation.
Use the sample code:
1 while(true){2String uuid =Uuid.randomuuid (). toString ();4 Booleanret = Lock.trygetdistributedlock (Redis, "nx_test", uuid, 5000);5 if(Ret! =false){6 //TODO implementing business logic7Lock.releasedistributedlock (Redis, "Nx_test", uuid);8 Break;9}Else{TenThread.Sleep (500); One } A}
Here, set the 5000 (5 seconds) time-out period, this time must be greater than the execution time of the business logic, otherwise there is no way to lock up.
Reference Blog https://wudashan.cn/2017/10/23/Redis-Distributed-Lock-Implement/
PS: Which great God knows how to get Jedis from Redistemplate, Redistemplate does not encapsulate the related function of set.
Java implements Redis distributed locks