The project needs redis distributed, so I encapsulated a set
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;
@Service
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 has slow sql, the timeout time is set a little longer
private static final long DEFAULT_EXPIRE = 80;// 80s has slow sql, the timeout time is set a little longer
private String key;
@Autowired
private RedisTemplate redisTemplate;
/**
* The time to wait for the lock, the unit is s
*
* @param key
* @param timeout s
* @param 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);// Temporarily set to expire after 80s to prevent abnormal interrupt lock from being released
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("add RedisLock["+key+"]."+ Thread.currentThread ());
}
return true;
}
TimeUnit.MILLISECONDS.sleep(1000 + new Random().nextInt(100));// Add random time to prevent livelock
}
} 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);
}
}
}