All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.gracerun.summermq.service.RedisService Maven / Gradle / Ivy

There is a newer version: 1.0.6
Show newest version
package com.gracerun.summermq.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisStringCommands;
import org.springframework.data.redis.connection.ReturnType;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.types.Expiration;
import org.springframework.data.redis.serializer.RedisSerializer;

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

/**
 * redis服务
 *
 * @author Tom
 * @version 1.0.0
 * @date 12/26/21
 */
@Slf4j
public class RedisService {

    private static final Long RELEASE_SUCCESS = 1L;
    private static final String RELEASE_LOCK_SCRIPT = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 加锁
     *
     * @param lockKey
     * @param seconds
     * @param supplier
     * @return
     */
    public boolean withRenderLock(String lockKey, long seconds, Supplier supplier) {
        String uuid = UUID.randomUUID().toString();
        boolean lockStatus = tryLock(lockKey, uuid, seconds);
        if (!lockStatus) {
            log.info("{} lock fail", lockKey);
            return false;
        }

        try {
            return supplier.get();
        } finally {
            releaseLock(lockKey, uuid);
        }
    }

    /**
     * redis分布式锁
     *
     * @param key     加锁键
     * @param value   加锁唯一标识,推荐使用UUID
     * @param seconds 锁过期时间,秒
     * @return
     */
    public Boolean tryLock(String key, String value, long seconds) {
        try {
            return stringRedisTemplate.execute((RedisCallback) (connection) ->
                    connection.set(stringRedisTemplate.getStringSerializer().serialize(key),
                            stringRedisTemplate.getStringSerializer().serialize(value),
                            Expiration.from(seconds, TimeUnit.SECONDS),
                            RedisStringCommands.SetOption.ifAbsent())
            );
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return false;
    }

    /**
     * 与 tryLock 相对应,用作释放锁
     *
     * @param key   释放锁键
     * @param value 释放锁唯一标识,必须与获取锁的value相同
     * @return
     */
    public Boolean releaseLock(String key, String value) {
        try {
            return stringRedisTemplate.execute((RedisCallback) redisConnection -> {
                RedisSerializer serializer = stringRedisTemplate.getStringSerializer();
                Long result = redisConnection.eval(serializer.serialize(RELEASE_LOCK_SCRIPT),
                        ReturnType.INTEGER, 1, serializer.serialize(key), serializer.serialize(value));
                if (RELEASE_SUCCESS.equals(result)) {
                    return Boolean.TRUE;
                }
                return Boolean.FALSE;
            });
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return false;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy