ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

Redis系列---【分布式锁解决方案之Redisson】

2022-06-24 12:36:53  阅读:167  来源: 互联网

标签:Redisson Redis --- org import lockKey redisTemplate stock


1.分布式锁解决方案

常用的一般有Zookeeper,Redisson,数据库。

  • Zookeeper方案使用的是CP(保证了一致性和分区容错性,牺牲了一点可用性),适合流量请求不是很大,一致性要求较高的业务场景。
  • Redisson方案使用的是AP(保证了可用性和分区容错性,牺牲了一点一致性),适合高并发场景,对一致性要求不是很高的业务场景。一致性可以人工通过脚本弥补,也可以通过redlock去解决。

2.Redission分布式锁解决方案

  1. 在pom中引入Redisson坐标
<dependency>
  <groupId>org.redisson</groupId>
  <artifactId>redisson</artifactId>
  <version>3.17.3</version>
</dependency>
  1. 在配置类或启动类中注入Redisson对象
    @Bean
    public Redisson redisson(){
        //redis为单机模式
        Config config = new Config();
        config.useSingleServer().setAddress("redis://localhost:6379").setPassword("123456");
        return (Redisson) Redisson.create(config);
    }
  1. 业务代码编写
package com.fast.controller;

import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @author hjw
 * @since 2022年06月23日 11:42:00
 */
@RestController
@RequestMapping("stock")
public class StockController {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private Redisson redisson;

    @GetMapping("init")
    public String init() {
        redisTemplate.opsForValue().set("stock", 100);

        return "库存新增成功";
    }

    @GetMapping("sale")
    public String saleGoods() {
        //这样写,单机部署不会有问题,多节点就会出问题,因为synchronized只能基于jvm做加锁,多个节点属于多个jvm了
        synchronized (this) {
            int stock = (int) redisTemplate.opsForValue().get("stock");
            if (stock > 0) {
                int i = stock - 1;
                redisTemplate.opsForValue().set("stock", i);
                System.out.println("库存剩余:" + i);
            } else {
                System.out.println("库存数量不足");
                return "库存数量不足";
            }
        }
        return "库存扣减成功";
    }

    @GetMapping("saleImprove")
    public String saleImprove() {
        //使用redisson实现分布式锁
        String lockKey = "product_001";
//        String clientId = UUID.randomUUID().toString();
        **RLock redissonLock = redisson.getLock(lockKey);**
        try {
            //使用redisTemplate还需要手写子线程每隔30s*1/3=10s,根据clientId给每个线程的lockKey进行续期,防止lockKey失效后,业务未执行完,结果下个线程进来了
//            Boolean result = redisTemplate.opsForValue().setIfAbsent(lockKey,clientId,30, TimeUnit.SECONDS);
//            if (!result){
//                return "error_code";
//            }
            **redissonLock.lock();**//相当于setIfAbsent(lockKey,clientId,30, TimeUnit.SECONDS);
            int stock = (int) redisTemplate.opsForValue().get("stock");
            if (stock > 0) {
                int i = stock - 1;
                redisTemplate.opsForValue().set("stock", i);
                System.out.println("库存剩余:" + i);
            } else {
                System.out.println("库存数量不足");
                return "库存数量不足";
            }
        }finally {
            **redissonLock.unlock();**
//            if (clientId.equals(redisTemplate.opsForValue().get(lockKey))){
//                redisTemplate.delete(lockKey);
//            }
        }
        return "库存扣减成功";
    }
}
  1. 若想进一步优化,则可以采用1.8中ConcurrentHashMap的设计思想,分段加锁
    进一步把库存1000,进行拆分成stock1-200,stock2-200,stock3-200,stock4-200,stock5-200,然后再进行分配,第一个请求进来访问stock1,进行库存加减,第二个访问stock2进行库存加减...依此类推,分别加锁解锁,就可以大大提高并发量。

标签:Redisson,Redis,---,org,import,lockKey,redisTemplate,stock
来源: https://www.cnblogs.com/hujunwei/p/16408347.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有