• 基于redis的分布式锁实现方案--redisson


    实例代码地址,请前往:https://gitee.com/GuoqingLee/distributed-seckill

    redis官方文档地址,请前往:http://www.redis.cn/topics/distlock.html

    前言

    关于分布式锁的实现,目前主流方案有以下三类:

    1、基于数据库的乐观锁;

    2、基于redis实现的锁服务;

    3、基于zookeeper的实现;

    网上关于怎么实现redis的分布式锁,一搜一大把的文章,有写的比较好的,也有明显存在缺陷的,非常容易误导初入这一块的初学者;

    而存在的问题,无外乎是setnx()-->expire(),保证不了原子性,容易出现死锁等情况,这里就不在去做解释了;

    本文的主旨是如何使用redis官方推荐的redisson实现redis的分布式锁;

    一、具体实现:

    maven引入需要的jar

    1 <dependency>
    2     <groupId>org.redisson</groupId>
    3     <artifactId>redisson-spring-boot-starter</artifactId>
    4     <version>3.10.1</version>
    5 </dependency>

    配置文件如下

    # common spring boot settings
    
    spring.redis.database=
    spring.redis.host=
    spring.redis.port=
    spring.redis.password=
    spring.redis.ssl=
    spring.redis.timeout=
    spring.redis.cluster.nodes=
    spring.redis.sentinel.master=
    spring.redis.sentinel.nodes=

    封装工具类:

      1 package cn.com.bluemoon.redis.lock;
      2 
      3 import java.util.concurrent.TimeUnit;
      4 
      5 import org.redisson.api.RLock;
      6 import org.redisson.api.RedissonClient;
      7 import org.springframework.beans.factory.annotation.Autowired;
      8 import org.springframework.stereotype.Component;
      9 
     10 /**
     11  * 基于Redisson的分布式锁实现
     12  * @author Guoqing.Lee
     13  * @date 2019年1月23日 下午4:04:57
     14  *
     15  */
     16 @Component
     17 public class RedissonDistributedLocker {
     18     
     19     @Autowired
     20     private RedissonClient redissonClient;
     21     
     22     /**
     23      * 加锁
     24      * @param lockKey
     25      * @return
     26      */
     27     public RLock lock(String lockKey) {
     28         RLock lock = redissonClient.getLock(lockKey);
     29         lock.lock();
     30         return lock;
     31     }
     32     
     33     /**
     34      * 加锁,过期自动释放
     35      * @param lockKey
     36      * @param leaseTime    自动释放锁时间
     37      * @return
     38      */
     39     public RLock lock(String lockKey, long leaseTime) {
     40         RLock lock = redissonClient.getLock(lockKey);
     41         lock.lock(leaseTime, TimeUnit.SECONDS);
     42         return lock;
     43     }
     44     
     45     /**
     46      * 加锁,过期自动释放,时间单位传入
     47      * @param lockKey
     48      * @param unit        时间单位
     49      * @param leaseTime    上锁后自动释放时间
     50      * @return
     51      */
     52     public RLock lock(String lockKey, TimeUnit unit, long leaseTime) {
     53         RLock lock = redissonClient.getLock(lockKey);
     54         lock.lock(leaseTime, unit);
     55         return lock;
     56     }
     57     
     58     /**
     59      * 尝试获取所
     60      * @param lockKey
     61      * @param unit        时间单位
     62      * @param waitTime    最多等待时间
     63      * @param leaseTime    上锁后自动释放时间
     64      * @return
     65      */
     66     public boolean tryLock(String lockKey, TimeUnit unit, long waitTime, long leaseTime) {
     67         RLock lock = redissonClient.getLock(lockKey);
     68         try {
     69             return lock.tryLock(waitTime, leaseTime, unit);
     70         } catch (InterruptedException e) {
     71             return false;
     72         }
     73     }
     74     
     75     /**
     76      * 尝试获取所
     77      * @param lockKey
     78      * @param waitTime    最多等待时间
     79      * @param leaseTime    上锁后自动释放锁时间
     80      * @return
     81      */
     82     public boolean tryLock(String lockKey, long waitTime, long leaseTime) {
     83         RLock lock = redissonClient.getLock(lockKey);
     84         try {
     85             return lock.tryLock(waitTime, leaseTime, TimeUnit.SECONDS);
     86         } catch (InterruptedException e) {
     87             return false;
     88         }
     89     }
     90     
     91     /**
     92      * 释放锁
     93      * @param lockKey
     94      */
     95     public void unlock(String lockKey) {
     96         RLock lock = redissonClient.getLock(lockKey);
     97         lock.unlock();
     98     }
     99     
    100     /**
    101      * 释放锁
    102      * @param lock
    103      */
    104     public void unlock(RLock lock) {
    105         lock.unlock();
    106     }
    107     
    108 }

    二、使用方式

    方式一:

     1     @Autowired
     2     private RedissonDistributedLocker redissonDistributedLocker;
     3 
     4         String lockKey = "BM_MARKET_SECKILL_" + stallActivityId;
     5     try {
     6                 //超过2S自动释放锁
     7         redissonDistributedLocker.lock(lockKey, 2L);
     8                 //业务处理
     9 
    10         } finally {
    11         redissonDistributedLocker.unlock(lockKey);  //释放锁
    12     }    

    方案二:

     1 @Autowired
     2 private RedissonDistributedLocker redissonDistributedLocker;
     3 
     4 public void test() throws InterruptedException {
     5     final int[] counter = {0};
     6 
     7         for (int i= 0; i < 100; i++){
     8         
     9             new Thread(new Runnable() {
    10 
    11                 @Override
    12 
    13                 public void run() {
    14                     boolean isGetLock = redissonDistributedLocker.tryLock("test0001", 3L, 1L);
    15                     if(isGetLock) {
    16                         try {
    17                             int a = counter[0];
    18                             counter[0] = a + 1;
    19                             logger.info(a + "");
    20                         } finally {
    21                             redissonDistributedLocker.unlock("test0001");
    22                         }
    23                     }
    24                 }
    25             }).start();
    26             
    27         }
    28 
    29         // 主线程休眠,等待结果
    30         Thread.sleep(5000);
    31         System.out.println(counter[0]);
    32         logger.info(counter[0] + "");
    33 }

    闲话就不多说了,希望能对你有所帮助。

  • 相关阅读:
    jedis 连接 虚拟机内redis服务
    数据库存储过程项目总结
    前端jsp联系项目相关经验
    学习做项目的一些随笔
    循环
    字典
    集合
    元组
    列表
    字符串
  • 原文地址:https://www.cnblogs.com/ocean-sky/p/10320627.html
Copyright © 2020-2023  润新知