项目需要redis 分布式所以自己封装了一套
package com.Tourism;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataAccessException; import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.core.RedisCallback; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.stereotype.Service;import com.Tourism.timed.task.OrderTask;
import java.util.Random;
import java.util.concurrent.TimeUnit; public class RedisUtils {private static final Logger LOGGER = Logger.getLogger(RedisUtils.class);
public static final String REDIS_LOCK = "RedisLock:";private static final long DEFAULT_WAIT_LOCK_TIME_OUT = 60;// 60s 有慢sql,超时时间设置长一点
private static final long DEFAULT_EXPIRE = 80;// 80s 有慢sql,超时时间设置长一点 private String key; @Autowired private RedisTemplate redisTemplate;/**
* 等待锁的时间,单位为s * * key * timeout s * seconds */ public boolean lock(String key, long timeout, TimeUnit seconds,String value) { String lockKey = generateLockKey(key); long nanoWaitForLock = seconds.toNanos(timeout); long start = System.nanoTime();try {
while ((System.nanoTime() - start) < nanoWaitForLock) { if (redisTemplate.getConnectionFactory().getConnection().setNX(lockKey.getBytes(), value.getBytes())) { redisTemplate.expire(lockKey, DEFAULT_EXPIRE, TimeUnit.SECONDS);// 暂设置为80s过期,防止异常中断锁未释放 if (LOGGER.isDebugEnabled()) { LOGGER.debug("add RedisLock["+key+"]."+ Thread.currentThread()); } return true; } TimeUnit.MILLISECONDS.sleep(1000 + new Random().nextInt(100));// 加随机时间防止活锁 } } catch (Exception e) { LOGGER.error(e.getMessage(), e); unlock(key,value); } return false; }public void unlock(String key,String value) {
try { String lockKey = generateLockKey(key); RedisConnection connection = redisTemplate.getConnectionFactory().getConnection(); Object object = redisTemplate.opsForValue().get("key"); if(object == null||!object.toString().equals(value)) { return ; } connection.del(lockKey.getBytes()); connection.del(key.getBytes()); connection.close(); } catch (Exception e) { LOGGER.error(e.getMessage(), e); } }private String generateLockKey(String key) {
return String.format(REDIS_LOCK + "%s", key); }
public void close() {
try { String lockKey = generateLockKey(key); if (LOGGER.isDebugEnabled()) { LOGGER.debug("release RedisLock[" + lockKey + "]."); } RedisConnection connection = redisTemplate.getConnectionFactory().getConnection(); connection.del(lockKey.getBytes()); connection.close(); } catch (Exception e) { LOGGER.error(e.getMessage(), e); } }}