订单新增时选择收款账号默认选择策划运营;添加修改订单时更新服务到期时间
This commit is contained in:
@ -0,0 +1,120 @@
|
||||
package com.stdiet.common.utils;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Component
|
||||
public class SynchrolockUtil {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
/**
|
||||
* 存储到redis中的锁标志
|
||||
*/
|
||||
private static final String LOCKED = "LOCKED";
|
||||
|
||||
/**
|
||||
* 默认请求锁的超时时间(ms 毫秒)
|
||||
*/
|
||||
private static final long TIME_OUT = 1000*60;
|
||||
|
||||
/**
|
||||
* 默认锁的有效时间(s)
|
||||
*/
|
||||
public static final int EXPIRE = 60*5;
|
||||
|
||||
/**
|
||||
* 锁flag
|
||||
*/
|
||||
private volatile boolean isLocked = false;
|
||||
|
||||
@Autowired
|
||||
private StringRedisTemplate redisTemplate;
|
||||
|
||||
/**
|
||||
* 默认锁时间60s
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public boolean lock(String key) {
|
||||
|
||||
return lock(key, EXPIRE, TIME_OUT);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* @param expireTime 锁时间,单位秒
|
||||
* @return
|
||||
*/
|
||||
public boolean lock(String key, int expireTime) {
|
||||
return lock(key, expireTime, TIME_OUT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key 锁定key
|
||||
* @param expireTime 锁过期时间 (秒)
|
||||
* @param timeOut 请求锁超时时间 (毫秒)
|
||||
* @return
|
||||
*/
|
||||
public boolean lock(String key, int expireTime, long timeOut) {
|
||||
// 系统当前时间,纳秒
|
||||
long nowTime = System.nanoTime();
|
||||
logger.info("key = {}, lock start time = {}.", key, nowTime / 1000000);
|
||||
// 请求锁超时时间,纳秒
|
||||
long timeout = timeOut * 1000000;
|
||||
final Random random = new Random();
|
||||
// 不断循环向Master节点请求锁,当请求时间(System.nanoTime() - nano)超过设定的超时时间则放弃请求锁
|
||||
// 这个可以防止一个客户端在某个宕掉的master节点上阻塞过长时间
|
||||
// 如果一个master节点不可用了,应该尽快尝试下一个master节点
|
||||
synchronized (this) {
|
||||
while ((System.nanoTime() - nowTime) < timeout) {
|
||||
// 将锁作为key存储到redis缓存中,存储成功则获得锁
|
||||
if (redisTemplate.opsForValue().setIfAbsent(key, LOCKED)) {
|
||||
isLocked = true;
|
||||
// 设置锁的有效期,也是锁的自动释放时间,也是一个客户端在其他客户端能抢占锁之前可以执行任务的时间
|
||||
// 可以防止因异常情况无法释放锁而造成死锁情况的发生
|
||||
redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
|
||||
|
||||
// 上锁成功结束请求
|
||||
break;
|
||||
}
|
||||
// 获取锁失败时,应该在随机延时后进行重试,避免不同客户端同时重试导致谁都无法拿到锁的情况出现
|
||||
// 睡眠10毫秒后继续请求锁
|
||||
try {
|
||||
Thread.sleep(10, random.nextInt(50000));
|
||||
} catch (InterruptedException e) {
|
||||
logger.error("获取分布式锁休眠被中断:", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
logger.info("key = {}, lock end time = {} ,spend time = {}ms.", key, nowTime / 1000000, (System.nanoTime() - nowTime) / 1000000);
|
||||
return isLocked;
|
||||
|
||||
}
|
||||
|
||||
public boolean isLock(String key) {
|
||||
//redisTemplate.getConnectionFactory().getConnection().time();
|
||||
return redisTemplate.hasKey(key);
|
||||
}
|
||||
|
||||
public void unlock(String key) {
|
||||
// 释放锁
|
||||
// 不管请求锁是否成功,只要已经上锁,客户端都会进行释放锁的操作
|
||||
if (isLock(key)) {
|
||||
long startTime = System.currentTimeMillis();
|
||||
logger.info("unlock key = {} start.", key, startTime);
|
||||
redisTemplate.delete(key);
|
||||
long endTime = System.currentTimeMillis();
|
||||
logger.info("unlock key = {} , end, spend time = {}ms.", key, (endTime - startTime));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user