Distributed Lock

Under conditions of high concurrency in many places to be used in a distributed locking, traditional architecture monomer lock synchronized, and can not meet the multi-node cluster mode, so now more mainstream should use a third-party middleware to achieve distributed lock.

 

Redis is locked setNX

Command Format

SETNX key value

The key value is set to value, if and only if the key does not exist. 
If a given key already exists, SETNX do nothing. 
SETNX is SET if Not eXists shorthand.

return value

Returns an integer, in particular 
1, when the key value is set 
to 0, when the value of the key is not set

example

redis> SETNX mykey “hello” 
(integer) 1 
redis> SETNX mykey “hello” 
(integer) 0 
redis> GET mykey 
“hello” 
redis>

 

Achieve 1 StringRedisTemplate

      This is based on a setnx implementation, the difference is locked returned result is a Boolean value, you can set the timeout while locked in the Advanced Edition, effectively avoid the problem of deadlock.

      

rely

<dependency>
   <groupId>org.springframework.data</groupId>
   <artifactId>spring-data-redis</artifactId>
   <version>2.1.5.RELEASE</version>
</dependency>

 

Code

        AccessToken oToken = null;
        StringRedisTemplate redisTemplate = new StringRedisTemplate();
boolean lockFlag = redisTemplate.opsForValue().setIfAbsent("access_token_" + appId, appSecrete, 15L, TimeUnit.SECONDS); if (lockFlag) { logger.info("加锁成功, 开始获取最新的token"); try { oToken = weixinUtil.getAccessToken_for_dist(appId, appSecrete); } finally { redisTemplate.delete("access_token_" + appId); logger.info("Unlock success." ); } } The else { logger.info ( "lock fails, return to the old token" ); }

 

Precautions:

  Since the lock timeout want to achieve at the same time, it is necessary spring-redis-data version of 2.1 or more, which requires jedis latest version of at least 2.9, and version springboot also need to reach more than 2.0.

  If springboot version is mainly the fault will be reported as follows:

2019-06-06 10:45:15.697 [main] ERROR org.springframework.boot.SpringApplication - Application startup failed
java.lang.NoSuchMethodError: org.springframework.data.repository.config.RepositoryConfigurationSource.getAttribute(Ljava/lang/String;)Ljava/util/Optional;
    at org.springframework.data.redis.repository.configuration.RedisRepositoryConfigurationExtension.registerBeansForRoot(RedisRepositoryConfigurationExtension.java:88)
    at org.springframework.data.repository.config.RepositoryConfigurationDelegate.registerRepositoriesIn(RepositoryConfigurationDelegate.java:116)
    at org.springframework.boot.autoconfigure.data.AbstractRepositoryConfigurationSourceSupport.registerBeanDefinitions(AbstractRepositoryConfigurationSourceSupport.java:59)
    at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsFromRegistrars(ConfigurationClassBeanDefinitionReader.java:359)
    at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:143)
    at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:116)

 

Guess you like

Origin www.cnblogs.com/goujh/p/10984050.html