• Redis分布式锁


    场景

    很多情况下我们会遇到这样的情况,程序根据数据的状态进行相应的操作,例如更新用户Token,分布式环境下,使得问题变得复杂,多个线程同时更新一条数据会导致状态出现未知状态,例如线程A看到用户User的Token过期就去刷新,此时线程B也做同样的操作,线程A先获取到新的Token,线程B后获取到新的Token,线程B的操作覆盖了线程A的操作,线程B又先刷新到缓存中去,线程A用无效的Token覆盖了缓存。
    此时我们就希望有一把分布式锁可以让线程单独执行该操作,分布式锁实现的方式有很多,利用MySQL,Redis都可以,这里我们专门介绍下Redis分布式锁的实现。

    加锁

    使用Redis的setnx功能实现加锁

    public boolean tryLock(String key, String value, Integer expire) {
        String result = jedis.set(lockKey, lockValue, "nx", "ex", expire);
        return "OK".equals(result, true);
    }
    

    循环加锁直到成功为止

    public void lock() {
        while (true) {
            if (tryLock()) return true;
            Thread.sleep(1000);
        }
    }
    

    解锁

    使用lua脚本实现解锁,而不是直接使用del直接删除,del可能会导致误删,使用lua脚本通过事务实现解。

    public boolean unlock(String key, String value) {
        String lua = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
        String result = jedis.eval(lua, key, value)
        return result == 0
    }
    

    转载于:https://my.oschina.net/u/2950586/blog/1827835

  • 相关阅读:
    Laravel5.0学习--01 入门
    MySQL账户安全设置
    360路由器c301最新固件支持万能中继
    PsySH:PHP交互运行环境
    PHP-CS-Fixer:格式化你的PHP代码
    JVM 类加载机制详解
    Java虚拟机(JVM)概述
    聊一聊 Spring 中的线程安全性
    Java 里如何实现线程间通信
    Java 数据结构
  • 原文地址:https://www.cnblogs.com/twodog/p/12136713.html
Copyright © 2020-2023  润新知