redis分布式锁(spring boot结合redis)

应用场景 : 例如一款手机只有10台的量秒杀,那么,在高并发的情况下,成千上万条数据更新数据库(例如10台的量被人抢一台就会在数据集某些记录下 减1),

       那次这个时候的先后顺序是很乱的,很容易出现10台的量,抢到的人就不止10个这种严重的问题。

主要通过redis的 setnx  和getset来对方法加锁

测试方法 : 使用apache的ab命令压测   ab -n 500 -c 100 http://127.0.0.1/xxxx

     -n 请求数量   -c 线程数量

1.引入相关jar包

<!--redis-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>        

2.配置application.yml

spring:
   redis:
      host: 192.168.12.39  #主机地址
      port: 8001    #端口号
      #password: 如果有密码就填写

3.代码实现

public class RedisLockService {
   //过期时间 10s
private static final int timeout = 10*1000; @Autowired private StringRedisTemplate stringRedisTemplate; /** * 加锁 * @param key * @param value 当前时间+ 过期时间 * @return */ public boolean lock(String key,String value){ //此方法就是调用setnx, 设置成功 if(stringRedisTemplate.opsForValue().setIfAbsent(key,value)){ return true; } //已存在,查看value是否过期 String currentValue = stringRedisTemplate.opsForValue().get(key); //过期时间 long time = timeout + System.currentTimeMillis() ; //获取时间小于(系统时间+过期时间),表示已过期 if(!StringUtils.isEmpty(currentValue) && Long.parseLong(currentValue) < time) { //返回旧值 ,设置新值 String oldValue = stringRedisTemplate.opsForValue().getAndSet(key,value); //这层判断防止两个进程同时进入,同时修改value值 if(!StringUtils.isEmpty(oldValue) && oldValue.equals(currentValue)){ return true; } } return false; } /** * 解锁 * @param key * @param value */ public void unLock(String key,String value){ try{ String currentValue = stringRedisTemplate.opsForValue().get(value); if(!StringUtils.isEmpty(currentValue)&& currentValue.equals(value)){ stringRedisTemplate.opsForValue().getOperations().delete(key); } }catch (Exception e){ log.error("redis分布锁解锁异常,"+e.getMessage()); } } }

4.使用方法

  在需要上锁的地方调用加锁方法

    @Autowired
    private RedisLockService redisLockService;
  
public void lockMethod(String key ,String value){ //1.拿锁 //没有拿到锁 if(!redisLockService.lock (key , value)){ throw new SellException(102,"人太多了,请换个姿势重试吧!"); } //2.执行加锁之后的逻辑 //3.解锁 redisLockService.unLock(key,value); }

 

posted @ 2018-08-12 17:33  qqq齐  阅读(159)  评论(0)    收藏  举报