在集群的情况下,用户多次请求接口时,存入的内容可能会导致重复,这时候就可以使用分布式锁来限制

适用场景

  分布式应用,分布式缓存,分布式回话管理,分布式服务(任务,延迟任务,执行器),分布式redis客户端

第一步:导入依赖

<!-- redis 分布式锁框架 -->
		<dependency>
			<groupId>org.redisson</groupId>
			<artifactId>redisson</artifactId>
			<version>3.12.5</version>
		</dependency>

第二步:配置连接redis

程序化配置方法

         Config config = new Config();
            //存放在哪个服务器的redisIP地址加redis端口号
         config. useSingleServer().setAddress("127.0.0.1:6379");

         RedissonClient redisson = Redisson.create(config);

验证是否连接成功

         redisson.getConfig().toJSON().toString()

结果 {"singleServerConfig":{"idleConnectionTimeout":10000,"pingTimeout":1000,"connectTimeout":10000,"timeout":3000,"retryAttempts":3,"retryInterval":1500,"reconnectionTimeout":3000,"failedAttempts":3,"subscriptionsPerConnection":5,"address":"redis://127.0.0.1:6379","subscriptionConnectionMinimumIdleSize":1,"subscriptionConnectionPoolSize":50,"connectionMinimumIdleSize":10,"connectionPoolSize":64,"database":0,"dnsMonitoring":false,"dnsMonitoringInterval":5000},"threads":0,"nettyThreads":0,"codec":{"class":"org.redisson.codec.JsonJacksonCodec"},"codecProvider":{"class":"org.redisson.codec.DefaultCodecProvider"},"resolverProvider":{"class":"org.redisson.liveobject.provider.DefaultResolverProvider"},"redissonReferenceEnabled":true,"useLinuxNativeEpoll":false}


测试写法

public class LockExamples {
    public static void main(String[] args) throws InterruptedException {
        // 默认连接上127.0.0.1:6379
        RedissonClient client = Redisson.create();
        // RLock 继承了 java.util.concurrent.locks.Lock 接口
        RLock lock = client.getLock("lock");

        lock.lock();
        System.out.println("lock acquired");

        Thread t = new Thread(() -> {
            //获取锁,传入要锁的key
            RLock lock1 = client.getLock("lock");
            //获取锁
            lock1.lock();
            System.out.println("lock acquired by thread");
            //解锁
            lock1.unlock();
            System.out.println("lock released by thread");
        });

        t.start();
        t.join(1000);
        
        lock.unlock();
        System.out.println("lock released");

        t.join();

        client.shutdown();
    }
}

飞花令的写法

    @Override
    @Transactional(rollbackFor = Exception.class)
    public FlyingFlowerV1Vo insert(FlyingFlowerReq flyingFlowerReq, String userId) throws Exception {
        //对进来的用户加锁
        RLock userLock = redissonClient.getLock(RedissonKey.USER_ID + userId);
        try{
            //尝试加锁, 最多等待1秒, 1000秒后自动解锁
            boolean getUserLock = userLock.tryLock(1, 1000, TimeUnit.MILLISECONDS);
            if (getUserLock) {
                //业务逻辑的代码,通常在插入修改的操作方法上进行加锁
        }catch (Exception e){
            //提示
            System.out.println("接令频繁"+ userId);
            throw new ResultInfo(ResultUtils.error("接令频繁,请稍后再试"));
        }finally {
            //解锁
            if (userLock.isLocked()) {
                if (userLock.isHeldByCurrentThread()) {
                    userLock.unlock();
                }
            }
        }
        return null;
    }

记录个人的成长,仅供参考

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐