订单新增时选择收款账号默认选择策划运营;添加修改订单时更新服务到期时间

This commit is contained in:
xiezhijun
2021-01-15 18:43:47 +08:00
parent c705665b45
commit 072b0a1f36
14 changed files with 978 additions and 22 deletions

View File

@ -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));
}
}
}