redis 分散式鎖的LUA實現
阿新 • • 發佈:2020-11-24
import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.script.DefaultRedisScript; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import java.util.Collections; import java.util.UUID; /** * @author tangjianghua * @date 2020/11/23 */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath:applicationContext.xml"}) public class RedisLock { @Autowired private RedisTemplate redisTemplate; public final String LUA_SETNX = "return redis.call('SET',KEYS[1],ARGV[1],'NX','EX',ARGV[2])"; public final DefaultRedisScript<String> REDIS_LOCK_SCRIPT = new DefaultRedisScript<>(LUA_SETNX, String.class); public final String LUA_DEL = "if (redis.call('GET', KEYS[1]) == ARGV[1]) then return redis.call('DEL',KEYS[1]) else return 0 end"; public final DefaultRedisScript<String> REDIS_UNLOCK_SCRIPT = new DefaultRedisScript<>(LUA_DEL, String.class); @Test public void test() { String key = "test"; String value = UUID.randomUUID().toString(); boolean lock = lock(key, value, 60L); System.out.println(lock); if(lock){ boolean unLock = unLock(key, value); System.out.println(unLock); } } public boolean lock(String key,String value,long expiration){ Object execute = redisTemplate.execute(REDIS_LOCK_SCRIPT, Collections.singletonList(key), value, String.valueOf(expiration)); return execute!=null && execute.equals("OK"); } public boolean unLock(String key,String value){ Object execute = redisTemplate.execute(REDIS_UNLOCK_SCRIPT, Collections.singletonList(key), value); return execute!=null && execute.equals(1L); } }