使用RedisTemplate实现分布式乐观锁

使用RedisTemplate实现分布式乐观锁,第1张

使用RedisTemplate实现分布式乐观锁 前言

使用乐观锁能够在不上锁的情况下实现线程安全,常用的实现方式就是使用CAS自旋的形式实现。

通常在分布式系统中有三种实现方式

数据库行级锁
Zookeeper实现分布锁
Redis实现乐观锁

三种方式各有优点,其中Redis和Zookeeper最常用,Redis性能最高,Zookeeper可靠性最高

代码实现

基于RedisTemplate,封装使用,通过IOC控制的方式实现:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;



@Component
public class RedisTemplateUtil {

    // 锁名称 prefix expire 锁对象
    public static final String LOCK_PREFIX = "RedisLock";
    // 加锁失效时间,毫秒,通常是业务执行时间的3-5倍
    public static final int LOCK_EXPIRE = 2000;
    // 轮询次数 根据项目而定
    public static final int COUNT = 20;
    // 轮询间隔时间  一般在50-100ms,根据项目而定
    public static final int INTERVAL = 50;


    @Autowired
    private RedisTemplate redisTemplate;

    
    public Boolean setLock(String key) {
        return redisTemplate.opsForValue().setIfAbsent(key, LOCK_PREFIX, LOCK_EXPIRE, TimeUnit.MILLISECONDS);
    }

    
    public Boolean deleteLock(String key) {
        return redisTemplate.delete(key);
    }


    
    public Boolean tryCasLock(String key) {
        int count = COUNT;//获取总轮询次数
        while (count > 0) {
            count--;
            if (setLock(key)) {
                return true;
            } else {
                try {
                    Thread.sleep(INTERVAL);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    throw new RuntimeException(false, StatusCode.ERROR, "服务器繁忙,请稍后再试。");
                }
            }
        }
        //如果一直没有取得锁,就返回false
        return false;
    }


}

使用:调用tryCasLock上锁,deleteLock解锁,解锁 *** 作放在finnally

@Service
public class OrderServiceImpl implements OrderService {

    //分布式锁
    @Autowired
    private RedisTemplateUtil redisLockUtils;


    
    @Override
    public void add() {
  
        //分布式锁,解决超额抢单问题
        long start = System.currentTimeMillis();
        if (redisLockUtils.tryCasLock(courseId + "")) {
          	try{
          	
            } finally {
                //释放锁
                redisLockUtils.deleteLock(courseId + "");
            }
        }

    }


}

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5605028.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-15
下一篇 2022-12-15

发表评论

登录后才能评论

评论列表(0条)

保存