redission分布式锁防止重复初始化问题

配置地址:

redisson:
  # Redis服务地址  如果集群使用","进行分割
  server-address: redis://${
          
   spring.redis.host}:${
          
   spring.redis.port}
  database: ${
          
   spring.redis.database}

创建配置类:

@ConfigurationProperties(prefix = "redisson")
@Configuration
public class RedissonConfig {
          
   
    /** Redis服务地址  如果集群使用","进行分割 */
    private String serverAddress;
    private Integer database;

    public String getServerAddress() {
          
   
        return serverAddress;
    }

    public void setServerAddress(String serverAddresss) {
          
   
        this.serverAddress = serverAddresss;
    }

    public Integer getDatabase() {
          
   
        return database;
    }

    public void setDatabase(Integer database) {
          
   
        this.database = database;
    }
}

注册redission Bean:

/**
     * RedissonClient
     * @return
     */
    @Bean
    public RedissonClient redissonClient(){
          
   
        String splitChar = ",";
        String serverAddress = redissonConfig.getServerAddress();
        String[] serverAddressArr = serverAddress.split(splitChar);

        Config config = new Config();
        if (serverAddressArr.length == 1) {
          
   
            //单例redis
            config.useSingleServer()
                    .setAddress(redissonConfig.getServerAddress())
                    .setDatabase(redissonConfig.getDatabase());
        } else {
          
   
            //集群redis
            config.useClusterServers().addNodeAddress(serverAddressArr);
        }
        return Redisson.create(config);
    }

防止重复初始化:

**
     * 初始化告警统计记录  保证告警统计不会被重复初始化
     *
     * @param areaId 部门id
     * @throws BizException
     */
    public void initWarningStatisticsSafe(String areaId) throws BizException {
          
   
    //创建锁名称
        String lockName = generateInitWarningStatisticsLockName(areaId);

        RLock lock = redisClient.getLock(lockName);
        try {
          
   
            //尝试获取锁 (最多尝试10秒,获取到后15秒后释放锁)
            boolean isAcquireLock = lock.tryLock(10, 15, TimeUnit.SECONDS);
            if (!isAcquireLock) {
          
   
                logger.error("初始化消息统计 ---  获取锁失败 lockName = " + lockName);
                throw new BizException("系统异常");
            } else {
          
   

                try {
          
   
                    //查询【告警统计】 (能够查询到最新的数据,因为默认隔离级别是read committed
                    List<WarningStatisticsPO> warningStatisticsPOS = warningStatisticsDAO.selectByArea(areaId);
                    if (CollectionUtils.isEmpty(warningStatisticsPOS)) {
          
   
                        //如果部门不存在告警统计,才进行初始化    initWarningStatistics()会开启一个新事务
                        warningStatisticsService.initWarningStatistics(areaId);
                    }
                } finally {
          
   
                    //释放锁 (在事务提交后才释放锁。保证其它事务在获取锁后能查询到数据,不会再进行初始化。)
                    lock.unlock();
                }

            }
        } catch (InterruptedException e) {
          
   
            e.printStackTrace();
        }
    }
经验分享 程序员 微信小程序 职场和发展