RedisTemplate implementa bloqueo distribuido a través de setNx

  • El cliente C2 usa SETNXcomandos para adquirir el bloqueo

  • Suponga que el cliente C1 se ha bloqueado pero aún mantiene el bloqueo, por lo que Redis devuelve falso al cliente C2

  • El Cliente C2 usa el GETcomando para adquirir el bloqueo y verificar si el bloqueo ha expirado. Si no caduca, continúe esperando un momento e intente nuevamente

  • Si el bloqueo ha expirado, el cliente C2 intenta GETSET lock.name <current Unix timestamp + lock timeout + 1>

  • Usando la GETSETsintaxis, el cliente C2 puede verificar si el valor anterior de la clave (el tiempo anterior del bloqueo) sigue siendo el tiempo de vencimiento y, de ser así, adquirir el bloqueo

  • Si otro cliente C3 es el primero en adquirir el bloqueo, el cliente C2 GETSETdevolverá el tiempo sin vencimiento después de ejecutar el comando, y luego el cliente C2 continuará intentando recuperar el bloqueo desde el principio. Esta operación cliente C2 extenderá el tiempo de vencimiento del bloqueo adquirido por el cliente C3, pero esto no es un gran problema.

/ ** 
     * Adquirir un bloqueo redis distribuido 
     * 
     * @param lockKey key bloqueado 
     * @param lockExpireMils La duración del bloqueo. Si el tiempo de espera no está desbloqueado, el subproceso de bloqueo se considera inactivo y otros subprocesos pueden tomar el bloqueo 
     * @return 
     * / 
    public boolean lock (String lockKey, long lockExpireMils) { 
        return (Boolean) redisTemplate.execute ((RedisCallback) connection-> { 
            long nowTime = System.currentTimeMillis (); 
            Boolean adquirir = conexión.setNX (lockKey.getBytes (), String.valueOf (nowTime + lockExpireMils + 1) .getBytes ()); 
            if (adquirir) { 
                return Boolean.TRUE; 
            } else { 
                byte [] valor = conexión.get (lockKey.getBytes ());
                if (Objects.nonNull (value) && value.length> 0) { 
                    long oldTime = Long.parseLong (new String (value)); 
                    if (oldTime <nowTime) {//connection.getSet 
                        : devuelve el valor anterior de esta clave y Establecer un nuevo valor. 
                        byte [] oldValue = connection.getSet (lockKey.getBytes (), String.valueOf (nowTime + lockExpireMils + 1) .getBytes ()); 
                        // Cuando la clave no se guarda, volverá vacía, indicando que la clave no existe o está en proceso usando 
                        retorno oldValue == null en false :? Long.parseLong (nuevo nuevo String (oldValue)) <nowtime; 
                    } 
                } 
            } 
            regreso Boolean.FALSE la; 
        }); 
    }

 

 

 

Dirección de referencia

RedisTemplate utiliza el comando SETNX para implementar el bloqueo distribuido  https://www.jianshu.com/p/6dd656e7051f

Supongo que te gusta

Origin www.cnblogs.com/panchanggui/p/12689058.html
Recomendado
Clasificación