In a multi-node deployment, the control of the lock, refer to:
Http://www.jeffkit.info/2011/07/1000/
Directly affixed to the code implementation, as in the same article, are based on the AOP
defining annotations, marking pointcuts:
Packagecom.ns.annotation;ImportJava.lang.annotation.ElementType;Importjava.lang.annotation.Inherited;Importjava.lang.annotation.Retention;ImportJava.lang.annotation.RetentionPolicy;ImportJava.lang.annotation.Target, @Target ({elementtype.method}) @Retention (retentionpolicy.runtime) @Inherited Public@InterfaceRedislock {/*** Redis Key *@return */String value (); /*** Lock time, unit milliseconds, default one minute*/ LongKeepmills ()default60000; /*** action when getting a failure*/lockfailaction Action ()defaultLockfailaction.giveup; Public enumlockfailaction{/*** Give up*/GiveUp,/*** Continue*/CONTINUE; } /*** Sleep time, set GiveUp ignore this item *@return */ LongSleepmills ()default1000;}
Facet implementations:
PackageCOM.NS.REDIS.AOP;ImportJava.lang.reflect.Method;ImportOrg.aspectj.lang.ProceedingJoinPoint;ImportOrg.aspectj.lang.annotation.Around;ImportOrg.aspectj.lang.annotation.Aspect;ImportOrg.aspectj.lang.annotation.Pointcut;Importorg.aspectj.lang.reflect.MethodSignature;ImportOrg.slf4j.Logger;Importorg.slf4j.LoggerFactory;Importorg.springframework.stereotype.Component;ImportCom.ns.annotation.RedisLock;Importcom.ns.annotation.RedisLock.LockFailAction;ImportCom.ns.redis.dao.base.BaseRedisDao; @Aspect Public classRedislockaspectextendsBaseredisdao<string, long>{ Private Static FinalLogger log = Loggerfactory.getlogger (redislockaspect.class); //Execution (* com.ns). *(*,..)) and @within (Com.ns.annotation.RedisLock)@Pointcut ("Execution (* com.ns). *(..)) && @annotation (Com.ns.annotation.RedisLock) ") Private voidLockpoint () {} @Around ("Lockpoint ()") PublicObject arround (Proceedingjoinpoint PJP)throwsthrowable{methodsignature methodsignature=(methodsignature) pjp.getsignature (); Method Method=Methodsignature.getmethod (); Redislock Lockinfo= Method.getannotation (Redislock.class); BooleanLock =false; Object obj=NULL; while(!Lock) { Longtimestamp = System.currenttimemillis () +Lockinfo.keepmills (); Lock=setnx (Lockinfo.value (), timestamp); //The old timestamp is still expired after getting the lock, expired, and successfully set, and can be considered to have acquired the lock (successfully set to prevent lock contention) Longnow =System.currenttimemillis (); if(Lock | | (Now > Getlock (lockinfo.value)) && (now >Getset (Lockinfo.value (), timestamp)))) { //get Lock, execute method, release lockLog.info ("Get lock ..."); Obj=pjp.proceed (); //do not add this line, for only one time the timing of the task, the difference can not guarantee that the other must just give up if(Lockinfo.action (). Equals (lockfailaction.continue)) {Delete (Lockinfo.value ()); } }Else{ if(Lockinfo.action (). Equals (Lockfailaction.continue)) {Log.info ("Re-request lock later ..."); Thread.CurrentThread (). Sleep (Lockinfo.sleepmills ()); }Else{log.info ("Discard lock ..."); Break; } } } returnobj; } Public Booleansetnx (String key,long value) {returnvalueoperations.setifabsent (key, value); } Public LongGetlock (String key) {returnValueoperations.get (key); } PublicLong getset (String key,long value) {returnValueoperations.getandset (key, value); } Public voidReleaseLock (String key) {delete (key); }}
Some of the above code only fits my current project scenario and adjusts to the actual needs
Deep understanding of the use of Spring Redis (ix), implementation of distributed locks via Redis