package com.tuoheng.api.utils;

import com.tuoheng.common.core.utils.StringUtils;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.SessionCallback;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @Author: 吴彬
 * @CreateTime: 2022-08-18  08:35
 * @Description: redis分布式锁工具栏
 * @Version: 1.0
 */
@Component
public class RedisSyncLock {
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * redis 分布式锁
     *
     * @param key
     * @param value
     * @param timeout
     * @param unit
     * @return
     */
    public boolean setLock(String key, String value, Long timeout, TimeUnit unit) {
        if (StringUtils.isEmpty(key) || StringUtils.isEmpty(value) || timeout == null || unit == null || timeout <= 0) {
            return false;
        }
        SessionCallback<Boolean> sessionCallback = new SessionCallback<Boolean>() {
            List<Object> exec = null;

            @Override
            public Boolean execute(RedisOperations operations) throws DataAccessException {
                operations.multi();
                stringRedisTemplate.opsForValue().setIfAbsent(key, value);
                stringRedisTemplate.expire(key, timeout, unit);
                exec = operations.exec();
                if (exec.size() > 0) {
                    return (Boolean) exec.get(0);
                }
                return false;
            }
        };
        return stringRedisTemplate.execute(sessionCallback);
    }

    /**
     * redis 释放锁
     *
     * @param key
     * @return
     */
    public Boolean unLock(String key) {
        return stringRedisTemplate.delete(key);//根据key删除缓存
    }
}
