防止重复提交分布式锁和redis延时提交机制

1.redis分布式锁

package com.swxc.core.lock;

import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import redis.clients.jedis.Transaction;
import redis.clients.jedis.exceptions.JedisException;

import javax.annotation.Resource;
import java.util.List;
import java.util.UUID;

/**
 * @作者:huangliang
 * @时间:2019-9-27 19:25
 * @注释:DistributedLock
 */
@Component
public class DistributedLock {

    @Resource
    private JedisPool jedisPool;


    public DistributedLock() {
    }

    /**
     * 加锁
     *
     * @param locaName       锁的key
     * @param acquireTimeout 获取超时时间
     * @param timeout        锁的超时时间
     * @return 锁标识
     */
    public String lockWithTimeout(String locaName,
                                  long acquireTimeout, long timeout) {
        Jedis conn = null;
        String retIdentifier = null;
        try {
            // 获取连接
            conn = jedisPool.getResource();
            // 随机生成一个value
            String identifier = UUID.randomUUID().toString();
            // 锁名,即key值
            String lockKey = "lock:" + locaName;
            // 超时时间,上锁后超过此时间则自动释放锁
            int lockExpire = (int) (timeout / 1000);

            // 获取锁的超时时间,超过这个时间则放弃获取锁
            long end = System.currentTimeMillis() + acquireTimeout;
            while (System.currentTimeMillis() < end) {
                if (conn.setnx(lockKey, identifier) == 1) {
                    conn.expire(lockKey, lockExpire);
                    // 返回value值,用于释放锁时间确认
                    retIdentifier = identifier;
                    return retIdentifier;
                }
                // 返回-1代表key没有设置超时时间,为key设置一个超时时间
                if (conn.ttl(lockKey) == -1) {
                    conn.expire(lockKey, lockExpire);
                }

                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        } catch (JedisException e) {
            e.printStackTrace();
        } finally {
            if (conn != null) {
                conn.close();
            }
        }
        return retIdentifier;
    }

    /**
     * 释放锁
     *
     * @param lockName   锁的key
     * @param identifier 释放锁的标识
     * @return
     */
    public boolean releaseLock(String lockName, String identifier) {
        Jedis conn = null;
        String lockKey = "lock:" + lockName;
        boolean retFlag = false;
        try {
            conn = jedisPool.getResource();
            while (true) {
                // 监视lock,准备开始事务
                conn.watch(lockKey);
                // 通过前面返回的value值判断是不是该锁,若是该锁,则删除,释放锁
                if (identifier.equals(conn.get(lockKey))) {
                    Transaction transaction = conn.multi();
                    transaction.del(lockKey);
                    List<Object> results = transaction.exec();
                    if (results == null) {
                        continue;
                    }
                    retFlag = true;
                }
                conn.unwatch();
                break;
            }
        } catch (JedisException e) {
            e.printStackTrace();
        } finally {
            if (conn != null) {
                conn.close();
            }
        }
        return retFlag;
    }
}

2.延时机制

package com.swxc.admin.utils;

import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import javax.annotation.Resource;

/**
 * @作者:huangliang
 * @时间:2019-9-12 9:07
 * @注释:JedisUtil
 */

@Component
public class JedisUtil {


    @Resource
    private JedisPool jedisPool;

    private Jedis getJedis() {
        return jedisPool.getResource();
    }

    /**
     * 设值
     *
     * @param key
     * @param value
     * @return
     */
    public String set(String key, String value) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.set(key, value);
        } catch (Exception e) {

            return null;

        } finally {
            close(jedis);
        }

    }

    /**
     * 设值
     *
     * @param key
     * @param value
     * @param expireTime 过期时间, 单位: s
     * @return
     */
    public String set(String key, String value, int expireTime) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.setex(key, expireTime, value);

        } catch (Exception e) {

            return null;

        } finally {

            close(jedis);

        }
    }
    /**
     * 取值
     *
     * @param key
     * @return
     */

    public String get(String key) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.get(key);

        } catch (Exception e) {

            return null;

        } finally {
            close(jedis);
        }

    }

    /**
     * 删除key
     *
     * @param key
     * @return
     */

    public Long del(String key) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.del(key.getBytes());

        } catch (Exception e) {

            return null;

        } finally {
            close(jedis);
        }

    }

    /**
     * 判断key是否存在
     *
     * @param key
     * @return
     */

    public Boolean exists(String key) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.exists(key.getBytes());
        } catch (Exception e) {

            return null;

        } finally {
            close(jedis);
        }

    }


    /**
     * 设值key过期时间
     *
     * @param key
     * @param expireTime 过期时间, 单位: s
     * @return
     */

    public Long expire(String key, int expireTime) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.expire(key.getBytes(), expireTime);
        } catch (Exception e) {

            return null;

        } finally {
            close(jedis);

        }

    }

    /**
     * 获取剩余时间
     *
     * @param key
     * @return
     */

    public Long ttl(String key) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.ttl(key);
        } catch (Exception e) {

            return null;
        } finally {
            close(jedis);
        }

    }

    private void close(Jedis jedis) {
        if (null != jedis) {
            jedis.close();
        }
    }


}

使用:

    @Autowired
    private DistributedLock distributedLock;

    @Autowired
    private JedisUtil jedisUtil;

    public boolean checkCacheHave(String account) {
        String s = jedisUtil.get(account);
        if ("TRUE".equals(s)) {
            return true;
        }
        jedisUtil.set(account, "TRUE", 5);
        return false;
    }



    //分布式锁
 String lockWithTimeout = distributedLock.lockWithTimeout("nameCache", 3000, 2000);


 distributedLock.releaseLock("txSettleAccounts",lockWithTimeout);

发布了117 篇原创文章 · 获赞 37 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/samHuangLiang/article/details/101697933