redis加锁和解锁

本文介绍了使用Redis实现分布式锁的代码示例,包括加锁和解锁操作,以及遇到的问题和解决方案。在加锁过程中,通过设置超时时间和使用NX与PX参数避免死锁。在解锁时,使用脚本确保只有拥有锁的线程才能释放锁。文章还提到了在实际运行中因资源释放导致的异常,并展示了优化后的加锁方法,确保了Jedis连接的正确关闭。
摘要由CSDN通过智能技术生成

本文章用于自己学习的操作,如果文章中有错误,麻烦各位留言指正,自己测试单流程是没有问题的

加锁

//调用加锁
boolean lock = redisService.getLock(resourceInfoId.toString(), String.valueOf(Thread.currentThread().getId()));
        if (lock == false) {
            return new FebsResponse().fail().message("当前资源正在审核中,请勿重复提交!");
        }
        
//调用解锁 ps:无论程序运行是否成功,都要释放锁,否则可能导致陷入死锁,如果是try方式,将解锁调用放在finally里面
try{

}finally{
redisService.releaseLock(resourceInfoId.toString(), String.valueOf(Thread.currentThread().getId()));
}
   


//静态参数
private static final String LOCK_SUCCESS = "OK";
private static final String SET_IF_NOT_EXIST = "NX";
private static final String SET_WITH_EXPIRE_TIME = "PX";
private static final Long RELEASE_SUCCESS = 1L;

//加锁方法
@Override
public boolean getLock(String key,String requestId) {

    String result = jedisPool.getResource().set(key, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, 10);
    if (LOCK_SUCCESS.equals(result)) {
        return true;
    }
    return false;
}        
    
//解锁方法
@Override
public boolean releaseLock(String key,String requestId) {
     String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
     Object result = jedisPool.getResource().eval(script, Collections.singletonList(key), Collections.singletonList(requestId));

     if (RELEASE_SUCCESS.equals(result)) {
         return true;
     }
     return false;
 }    
ps:上述代码不够完善,上线后发现,程序报错异常信息:Could not get a resource from the pool,然后修改一下,示例一下加锁方法,解锁方法同样要释放连接池
 public boolean getLock(String key,String requestId) {
    Jedis jedis = null;
     try{
         jedis = jedisPool.getResource();
         String result = jedis.set(key, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, 10);
         if (LOCK_SUCCESS.equals(result)) {
             return true;
         }
     }finally {
         if(null != jedis){
             jedis.close();
         }
     }
     return false;
 }

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RedisLock 是一个基于 Redis 实现的分布式锁,可以用于控制多个节点对某个资源的访问。下面是使用 RedisLock 实现分布式锁的 Java 代码示例: ```java // 引入 RedisLock 相关包 import com.github.fppt.jedismock.RedisServer; import org.redisson.Redisson; import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import org.redisson.config.Config; import org.redisson.config.SingleServerConfig; import org.redisson.misc.RedisRunner; import java.io.IOException; import java.net.ServerSocket; public class OrderService { private RedissonClient redissonClient; private RedisServer redisServer; public OrderService() throws IOException { // 启动 Redis 服务器 redisServer = RedisRunner.getDefault().run(); // 初始化 Redisson 客户端 Config config = new Config(); SingleServerConfig serverConfig = config.useSingleServer(); serverConfig.setAddress(redisServer.getHost() + ":" + redisServer.getBindPort()); redissonClient = Redisson.create(config); } public void placeOrder(String orderId) throws InterruptedException { // 获取 Redisson 锁 RLock lock = redissonClient.getLock("order:" + orderId); boolean locked = lock.tryLock(10, 100, TimeUnit.SECONDS); // 尝试获取锁,等待 10s,锁定 100s if (locked) { try { // 执行订单操作 } finally { lock.unlock(); // 释放锁 } } else { // 获取锁失败,抛出异常或者等待一段时间后重试 throw new IllegalStateException("Failed to acquire order lock"); } } public void stop() throws IOException { // 停止 Redis 服务器和 Redisson 客户端 redissonClient.shutdown(); redisServer.stop(); } public static void main(String[] args) throws IOException { OrderService orderService = new OrderService(); orderService.placeOrder("123"); orderService.stop(); } } ``` 在上面的代码中,我们首先启动了一个 Redis 服务器,然后通过 Redisson 创建了一个 Redisson 客户端。在 placeOrder 方法中,我们获取了一个名为 "order:orderId" 的 Redisson 锁,通过 tryLock 方法尝试获取锁,等待时间为 10s,锁定时间为 100s。如果获取锁成功,则执行订单操作,并在最后释放锁;否则,抛出异常或者等待一段时间后重试。最后,在 main 方法中,我们启动了 OrderService 并执行了一次 placeOrder 方法,并在最后停止了 Redis 服务器和 Redisson 客户端。 需要注意的是,RedisLock 的实现依赖于 Redisson,因此需要在项目中引入 Redisson 的相关依赖。另外,需要注意 RedisLock 的锁定时间,避免因为锁定时间过长导致资源被长时间占用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值