In order to prevent users from repeatedly clicking on the page or initiating multiple requests at the same time, request processing requires the operation of the Redis cache, which requires concurrent lock control of the concurrency boundary to realize the idea:
Since the token of each page's request is unique, token can be used as the lock (key) and the current time as value for concurrent lock control, divided into two methods: Acquirelock and Realeaselock
/**attempt to acquire a lock and set a valid time*/53+ Public BooleanAcquirelock (String Lock,Longexpired) { 54+BooleanIssuccess =false; 55+ Jedis Jedis =Jedispool.getresource (); 56+LongValue = System.currenttimemillis () + expired + 1; 57+Longacquired =jedis.setnx (lock, string.valueof (value)); 58+if(Acquired = = 1) 59+ issuccess =true; 60+Else { 61+LongOldValue =long.valueof (Jedis.get (lock)); 62+//If a lock has timed out before another resource has been acquired63+if(OldValue <System.currenttimemillis ()) { 64+ String GetValue =Jedis.getset (lock, string.valueof (value)); 65+if(long.valueof (getValue) = =oldValue)66+ issuccess =true; 67+Else68+ issuccess =false; 69+ } 70+ElseIssuccess =false; 71+ } 72+Jedispool.returnresource (Jedis); 73+returnissuccess; 74+ } 75+ 76+/**Releasing lock Resources*/77+ Public voidReleaseLock (String lock) {78+ Jedis Jedis =Jedispool.getresource (); 79+LongCurrentTime =System.currenttimemillis (); 80+if(CurrentTime <long.valueof (Jedis.get (lock))) { 81+Jedis.del (lock); 82+ } 83+Jedispool.returnresource (Jedis); 84+}
After the code review, against the open source Jedislock source code, found that the above implementation of the logic problem is that for Jedispool.getresource if an exception occurs, there is no exception processing, in the outer packaging class plus the following processing:
Object runTask (Callback Callback) {Jedis Jedis=NULL; BooleanBroken =false; Try{Jedis=Jedispool.getresource (); returnCallback.ontask (Jedis); } Catch(jedisexception e) {broken=handlejedisexception (e); } Catch(Exception e) {log.error ("Redis RunTask Error:", E); } finally{closeresource (Jedis, broken); Jedis=NULL; } return NULL; }
Private Booleanhandlejedisexception (jedisexception jedisexception) {if(jedisexceptioninstanceofjedisconnectionexception) {Log.error ("Redis connection lost.", jedisexception); } Else if(jedisexceptioninstanceofjedisdataexception) { if(Jedisexception.getmessage ()! =NULL) && (Jedisexception.getmessage (). IndexOf ("READONLY")! =-1) {log.error ("Redis connection is read-only slave.", jedisexception); } Else { //dataexception, Isbroken=false return false; } } Else{log.error ("Jedis exception happen.", jedisexception); } return true; }
Private void Boolean Conectionbroken) { try { if (conectionbroken) { Jedispool.returnbrokenresource ( Jedis); Else { jedispool.returnresource (Jedis); } Catch (Exception e) { log.error ("Return back Jedis failed, would fore close the Jedis.") , e); Jedis.close (); } }
Redis Concurrency Lock control