zoukankan      html  css  js  c++  java
  • 分布式锁-Redisson(一)

       一、pom依赖

       <!--springboot data redis-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-pool2</artifactId>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/org.redisson/redisson -->
            <dependency>
                <groupId>org.redisson</groupId>
                <artifactId>redisson</artifactId>
                <version>3.15.5</version>
            </dependency>

    二、yml文件

    spring:
      redis:
        host: 127.0.0.1
        port: 6379
        database: 0
        timeout: 1000
        password: 961230
        lettuce:
          pool:
            max-active: 100
            max-wait: -1
            min-idle: 0
            max-idle: 20
        ssl: false
    
    eureka:
      client:
        service-url:
          defaultZone: http://localhost:7900/eureka/
    
    redisson:
      address: redis://127.0.0.1:6379
      password: 961230
      database: 1
      timeout: 10000

    三、获取 Redisson 配置信息

    package com.dongliang.lcnorder.config.lock;
    
    import lombok.Data;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    
    /**
     * @author D-L
     * @version 1.0.0
     * @ClassName RedissonProperties.java
     * @Description 获取 Redisson 配置信息
     * @createTime 2021-06-04 23:40:00
     */
    
    @ConfigurationProperties(prefix = "redisson")
    @Data
    public class RedissonProperties {
    
        private int timeout = 3000;
    
        private String address;
    
        private String password;
    
        private int connectionPoolSize = 64;
    
        private int connectionMinimumIdleSize = 10;
    
        private int slaveConnectionPoolSize = 250;
    
        private int masterConnectionPoolSize = 250;
    
        private String[] sentinelAddresses;
    
        private String masterName;
    
        private int database;
    }

    四、自动配置 初始化bean

    package com.dongliang.lcnorder.config.lock;
    
    import org.redisson.Redisson;
    import org.redisson.api.RedissonClient;
    import org.redisson.config.Config;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
    import org.springframework.boot.context.properties.EnableConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    /**
     * @author D-L
     * @version 1.0.0
     * @ClassName RedissonAutoConfiguration.java
     * @Description Redisson 自动配置 初始化bean
     * @createTime 2021-06-04 23:40:00
     */
    
    @Configuration
    @EnableConfigurationProperties(RedissonProperties.class)
    public class RedissonAutoConfiguration {
    
        @Autowired
        private RedissonProperties properties;
    
        @Bean(name = "redissonClient")
        @ConditionalOnProperty(name = "redisson.address")
        RedissonClient redissonSingle() {
            Config config = new Config();
            config.useSingleServer().setAddress(properties.getAddress())
                    .setPassword(properties.getPassword())
                    .setTimeout(properties.getTimeout())
                    .setDatabase(properties.getDatabase())
                    .setConnectionPoolSize(properties.getConnectionPoolSize())
                    .setConnectionMinimumIdleSize(properties.getConnectionMinimumIdleSize())
                    .setPingConnectionInterval(60);
            return Redisson.create(config);
        }
    
        @Bean
        RedissonDistributedLock distributedLocker() {
            RedissonDistributedLock distributedLocker = new RedissonDistributedLock();
            distributedLocker.setRedissonClient(redissonSingle());
            return distributedLocker;
        }
    }

    五、定义分布式锁工具类

    package com.dongliang.lcnorder.config.lock;
    
    /**
     * @author D-L
     * @version 1.0.0
     * @ClassName DistributedLocker.java
     * @Description
     * @createTime 2021-06-04 23:40:00
     */
    public interface DistributedLock {
    
        void lock(String entityId);
    
        void unlock(String entityId);
    
        void lock(String entityId, int timeout);
    }
    package com.dongliang.lcnorder.config.lock;
    
    import org.redisson.api.RLock;
    import org.redisson.api.RedissonClient;
    
    import java.util.concurrent.TimeUnit;
    
    /**
     * @author D-L
     * @version 1.0.0
     * @ClassName RedissonDistributedLocker.java
     * @Description
     * @createTime 2021-06-04 23:40:00
     */
    
    public class RedissonDistributedLock implements DistributedLock {
        
        private RedissonClient redissonClient;
    
        @Override
        public void lock(String entityId) {
            RLock lock = redissonClient.getLock(entityId);
            lock.lock();
        }
    
        @Override
        public void unlock(String entityId) {
            RLock lock = redissonClient.getLock(entityId);
            if(lock!=null){
                if(lock.isLocked() && lock.isHeldByCurrentThread()) {
                    lock.unlock();
                }
            }
        }
    
        @Override
        public void lock(String entityId, int leaseTime) {
            RLock lock = redissonClient.getLock(entityId);
            lock.lock(leaseTime, TimeUnit.SECONDS);
        }
    
        public void setRedissonClient(RedissonClient redissonClient) {
            this.redissonClient = redissonClient;
        }
    }

    六、使用

        @Autowired
        private UserDao userDao;
    
        @Autowired
        private DistributedLock Locker;
    
    
        @Override
        @Transactional(rollbackFor = Exception.class)
        public void createOrder(TblOrder order) {
            log.info("createOrder --- beginning:" + order.getOrderName());
            if (order == null) {
                return;
            }
            try {
                //加分布式锁,保证操作幂等性
                Locker.lock(order.getOrderName() + order.getUid() + order.getPayType()  , 30);
                //创建订单
                buildOrder(order);
                log.info("createOrder --- success:" + order.getOrderName());
            }catch (Exception e) {
                throw new CustomizeException("createOrder --- error");
            }finally {
                Locker.unlock(order.getOrderName() + order.getUid() + order.getPayType());
            }
        }
    
        @Transactional(rollbackFor = Exception.class)
        protected void buildOrder( TblOrder order) {
            //构建订单明细并补充订单数据
            order.setCreateTime(new Date());
            orderDao.insert(order);
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
  • 相关阅读:
    用 Go 实现一个 LRU cache
    【转】入行软件测试,零基础拿OFFER
    【转】IntelliJ idea 高效使用教程,一劳永逸!
    python连接Oracle报错DPI1047
    【转】Pycharm快捷键设置(鼠标滚动控制字体大小)
    【转】Ubuntu:命令行安装可视化界面
    【转】Windows 如何在cmd命令行中查看、修改、删除与添加环境变量
    VAR多变量预测
    windows进程管理
    git关闭filemode
  • 原文地址:https://www.cnblogs.com/dongl961230/p/14845273.html
Copyright © 2011-2022 走看看