您现在的位置是:网站首页 > 代码编程 > JAVA开发JAVA开发

【原】spring项目中利用redis + lua脚本简单实现分布式锁

不忘初心 不忘初心 2019-03-18 围观() 评论() 点赞() JAVA开发

简介:在以往的单机系统中,为了做到线程安全,我们可以使用jdk提供给我们的synchronized关键字,也可以使用juc包下面的Lock,但是在现在流程的SOA服务

在以往的单机系统中,为了做到线程安全,我们可以使用jdk提供给我们的synchronized关键字,也可以使用juc包下面的Lock,但是在现在流程的SOA服务中,显然就没法用了,毕竟服务器再也不是同一台了,你管得了自己,管不了别人。

有问题,那就会有解决方案,那就是分布式锁,通常利用Redis或者Zookeeper来实现,亦或者是利用三方框架来解决(redisson),今天来教大家用redis实现一个超级简单的分布式锁。

实现思路:setnx + lua

setNx:全名“set if not exist”,如果key不存在就set,如果key已存在就不set;

LUA:lua 脚本功能是Reids 2.6版本的最大亮点,通过内嵌对 Lua 环境的支持,Redis解决了长久以来不能高效地处理CAS(check-and-set)命令的缺点;

废话不多说,直接上代码了

/**
 * set lock in redis, setNx(SET if Not eXists)
 *
 * @param key    key
 * @param value  value
 * @param expire second
 * @return result(0 - false, 1 - true)
 */
public Long setLock(String key, String value, Integer expire) {
    return redisTemplateJDKSerialization.execute((RedisCallback<Long>) connection -> {

        StringRedisSerializer serializer = new StringRedisSerializer();
        StringBuilder lua = new StringBuilder();

        lua.append("local key = KEYS[1]");
        lua.append("local value = ARGV[1]");
        lua.append("local ok = redis.call('setnx', key, value)");

        if (expire != null && expire > 0) {
            lua.append("local ttl = ARGV[2]");
            lua.append("if ok == 1 then");
            lua.append("    redis.call('expire', key, ttl)");
            lua.append("end ");

            lua.append("return ok");

            return connection.eval(serializer.serialize(lua.toString()), ReturnType.INTEGER, 1, serializer.serialize(key), serializer.serialize(value), serializer.serialize(expire.toString()));
        }

        lua.append("return ok");

        return connection.eval(serializer.serialize(lua.toString()), ReturnType.INTEGER, 1, serializer.serialize(key), serializer.serialize(value));
    });
}

上述代码中,不用lua脚本也是可以的,但是用了lua脚本会有一个更好的效果:

1、多个命令一次性提交,减少开销;

2、将内部的所有命令封装为一个原子操作;

3、执行之后lua脚本会保存在redis中,可多次复用;

redis分布式锁spring-redis

看完文章,有任何疑问,请加入群聊一起交流!!!

很赞哦! ()

文章评论

  • 请先说点什么
    人参与,条评论

请使用电脑浏览器访问本页面,使用手机浏览器访问本页面会导致下载文件异常!!!

雨落无影

关注上方公众号,回复关键字【下载】获取下载码

用完即删,每次下载需重新获取下载码

若出现下载不了的情况,请及时联系站长进行解决

站点信息

  • 网站程序:spring + freemarker
  • 主题模板:《今夕何夕》
  • 文章统计:篇文章
  • 标签管理标签云
  • 微信公众号:扫描二维码,关注我们