Redis_配合Lua做Java分布式事务锁

本文介绍了使用Redis作为Java分布式锁的方法。首先需检查Redis版本,2.6.0以上才支持执行Lua脚本;接着编写做分布式锁的Lua脚本;然后通过DOS窗口让Redis客户端调用该脚本;最后展示了Java整合Redis的代码,且项目测试整合成功。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Redis作Java分布式锁

 我们都知道redis现在成为越来越多人作为缓存工具的选择,redis在性能、操作等方面上有着独特的优势。

1. 检查reids版本
  因为redis是在2.6版本后才内置了Lua脚本解释器,所以也就是说要用redis执行lua脚本,最基本的要求就是redis版本必须是2.6.0以上
  查看redis版本命令:info
在启动redis客户端后,连接redis客户端,输入命令如下图:
查询redis版本号命令
 

2.编写lua脚本
  做分布式锁的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

 这个lua脚本的意思是传三个值,第一个值是键,第二个值是值,第三个值是过期时间,单位秒。

3.使用DOS窗口让redis客户端调用lua脚本
使用DOS命令调用

命令为:redis-cli.exe --eval E:\redis\redisLock.lua testKey testValue 300--前有个空格)

参数解释
redis-cli.exe调用该服务
–eval告诉redis客户端进行执行lua脚本
E:\redis\redisLock.lua这边是我自己的路径,换成你们lua脚本路径
testKey、testValue、300这个lua脚本接受的数据,根据你自己编写的lua脚本而定

结果
 我们可以看到我们设置的redis的结果和我们预期的是一样的。

4.Java整合Redis

 先上Java上的代码:

package com.dahantc.iot.util;

import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
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.stereotype.Service;

import com.dahantc.iot.core.util.LogUtil;

@Service
public class LuaRedisLockUtils{
	
	private final static Logger logger = LogUtil.get();
	
	@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);
			//设置返回类型
			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){
			logger.error("redis分布式锁存在异常,请注意key:{},value:{}, seconds:{}", key, value, seconds);
			return false;
		}
	}

}

lua脚本位置
 该项目过测试,整合是成功。这边不再跑一遍作示范了。

总结:BASE理论面向的是大型高可用可扩展的分布式系统,和我们传统的ACID型事务是背道而驰的。传统ACID事务要求的是强一致性,而分布式系统则是通过牺牲强一致性来换取可用型,允许数据在某较短的时间内不一致,当然分布式系统也是要保证数据的最终一致性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值