java使用redisTemplate执行lua脚本

redis_lock.lua

local key = KEYS[1]
local value = KEYS[2]
local sec = KEYS[3]

local result = redis.call("SET",key, value, "NX", "EX", sec)
if(result) then
	return 1
else
	return 0;
end

//TestLua.java 测试代码

import org.junit.Test;
import org.junit.runner.RunWith;
import org.luaj.vm2.Globals;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.lib.jse.JsePlatform;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.scripting.ScriptSource;
import org.springframework.scripting.support.ResourceScriptSource;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {Application.class})
public class TestLua {

    @Test
    public void t() {
        long l = TimeUnit.SECONDS.toMillis(15L);
        System.out.println(l);
    }

    @Test
    public void t2() {
        String luaStr = "print 'hello,world!'";
        Globals globals = JsePlatform.standardGlobals();
        LuaValue chunk = globals.load(luaStr);
        chunk.call();
    }

    private static final Logger logger = LoggerFactory.getLogger(TestLua.class);


    @Autowired
    private RedisTemplate redisTemplate;

    public Boolean lock(String key, String value, String seconds){
        try{
            String path = "redis_lock.lua";
            ClassPathResource resource = new ClassPathResource(path);
            ScriptSource scriptSource = new ResourceScriptSource(resource);
            DefaultRedisScript defaultRedisScript = new DefaultRedisScript();
            defaultRedisScript.setScriptSource(scriptSource);

            logger.info(scriptSource.getScriptAsString());

            //设置返回类型
            defaultRedisScript.setResultType(Long.class);

            //组装数据
            List<Object> keyList = new ArrayList<>();
            keyList.add(key);
            keyList.add(value);
            keyList.add(seconds);
            // 第三个参数是无用的,但不能为空,考虑到内存空间,遂作故用
            Long result = (Long)redisTemplate.execute(defaultRedisScript, keyList);
            return result == 1;
        }catch(Exception e){
            e.printStackTrace();
            logger.error("redis分布式锁存在异常,请注意key:{},value:{}, seconds:{}", key, value, seconds);
            return false;
        }
    }


    @Test
    public void testLock() {
        lock("testKey1","testValue2","300");
    }

}

posted @ 2021-09-03 09:22  ??,uunu  阅读(1584)  评论(0编辑  收藏  举报