日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

redis的hmset乐观锁的实现

發(fā)布時(shí)間:2023/12/13 综合教程 33 生活家
生活随笔 收集整理的這篇文章主要介紹了 redis的hmset乐观锁的实现 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1.lua腳本(集成實(shí)現(xiàn)了樂觀鎖,hmset ,expire等)

local key=KEYS[1];
local oldVerion=tonumber(ARGV[1]);
local seconds=ARGV[2];
local fieldLen = table.getn(ARGV)-2;
local idx=1;
local argvIdx=1;
local version = redis.call('HINCRBY',key,'version','0');
if(version~=oldVerion) then
    return 0;
end
for idx=1,fieldLen,2 do 
    argvIdx=idx+2;
    redis.call('HSet',key,ARGV[argvIdx],ARGV[argvIdx+1]);
end 
version =redis.call('HINCRBY',key,'version','1');
redis.call('EXPIRE',key,seconds);
return version;

2.eval直接調(diào)用測(cè)試

傳入?yún)?shù)

keysCount: 1

key: key11

version: 0

ttl: 6000

field1: icbc

field2:wh

eval "local key=KEYS[1];local oldVerion=tonumber(ARGV[1]);local seconds=ARGV[2];local fieldLen = table.getn(ARGV)-2;local idx=1;local argvIdx=1;local version = redis.call('HINCRBY',key,'version','0');if(version~=oldVerion) then return 0; end for idx=1,fieldLen,2 do argvIdx=(idx-1)+1+2; redis.call('HSet',key,ARGV[argvIdx],ARGV[argvIdx+1]); end version =redis.call('HINCRBY',key,'version','1');redis.call('EXPIRE',key,seconds);return version;"  1 key11 0 6000 field1 icbc field2 wh

3.java代碼

 @Autowired
    private StringRedisTemplate redisTemplate;

    private static final String LUA_SCRIPT_HMSETBYVERSION = "local key=KEYS[1];
" +
            "local oldVerion=tonumber(ARGV[1]);
" +
            "local seconds=ARGV[2];
" +
            "local fieldLen = table.getn(ARGV)-2;
" +
            "local idx=1;
" +
            "local argvIdx=1;
" +
            "local version = redis.call('HINCRBY',key,'version','0');
" +
            "if(version~=oldVerion) then
" +
            "	return 0;
" +
            "end
" +
            "for idx=1,fieldLen,2 do 
" +
            "argvIdx=idx+2;
" +
            "redis.call('HSet',key,ARGV[argvIdx],ARGV[argvIdx+1]);
" +
            "end 
" +
            "version =redis.call('HINCRBY',key,'version','1');
" +
            "redis.call('EXPIRE',key,seconds);
" +
            "return version;";
    private static final String LUA_SCRIPT_HMSETBYVERSION_SHA1 = SHA1.encode(LUA_SCRIPT_HMSETBYVERSION);
public long compareAndHMset(String key, int version, Map<String, String> values, int seconds) {
        if (CollectionUtils.isEmpty(values)) {
            return 0;
        }

        List<String> keys = Collections.singletonList(key);
        List<String> argvs = new ArrayList<>(values.size() * 3);
        
        argvs.add(Integer.toString(version));
        argvs.add(Integer.toString(seconds));

        for (Map.Entry<String, String> item : values.entrySet()) {
            argvs.add(item.getKey());
            argvs.add(Strings.isNullOrEmpty(item.getValue()) ? "" : item.getValue());
        }

        Long result = redisTemplate.execute(new RedisCallback<Long>() {
            @Override
            public Long doInRedis(RedisConnection connection) throws DataAccessException {
                Object nativeConnection = connection.getNativeConnection();
                // 集群模式和單點(diǎn)模式雖然執(zhí)行腳本的方法一樣,但是沒有共同的接口,所以只能分開執(zhí)行
                // 集群
                if (nativeConnection instanceof JedisCluster) {
                    try {
                        return (Long) ((JedisCluster) nativeConnection).evalsha(LUA_SCRIPT_HMSETBYVERSION_SHA1,
                                keys,
                                argvs);
                    } catch (redis.clients.jedis.exceptions.JedisNoScriptException ex) {
                        return (Long) ((JedisCluster) nativeConnection).eval(LUA_SCRIPT_HMSETBYVERSION, keys, argvs);
                    } catch (Exception ex) {
                        return 0L;
                    }
                } else {
                    // 單點(diǎn) 或 哨兵
                    try {
                        return (Long) ((Jedis) nativeConnection).evalsha(LUA_SCRIPT_HMSETBYVERSION_SHA1,
                                keys,
                                argvs);
                    } catch (redis.clients.jedis.exceptions.JedisNoScriptException ex) {
                        return (Long) ((Jedis) nativeConnection).eval(LUA_SCRIPT_HMSETBYVERSION, keys, argvs);
                    } catch (Exception ex) {
                        return 0L;
                    }
                }
            }
        });

        return result;
    }

4.調(diào)用

return 0 < compareAndHMset("hashkey11",
                1,
                ImmutableMap.of("field1", "icbc2"),
                6000
        );

總結(jié)

以上是生活随笔為你收集整理的redis的hmset乐观锁的实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。