分布式非公平锁实现、路径参数正则表达式修改增强

main
youHong.ai 2022-12-11 16:51:14 +08:00
parent 50989aa997
commit 2d4bce9513
7 changed files with 623 additions and 66 deletions

View File

@ -186,7 +186,7 @@ public class Util extends weaver.general.Util {
String str = sqlBuilder.toString().trim();
String removeSeparator = ",";
if (str.endsWith(removeSeparator)) {
// 如果以分割号结尾,则去除分割号
// 如果以分割号结尾,则去除分割号
str = str.substring(0, str.length() - 1);
}
if (str.trim().startsWith(removeSeparator)) {
@ -205,7 +205,7 @@ public class Util extends weaver.general.Util {
public static String removeSeparator(StringBuilder sqlBuilder, String removeSeparator) {
String str = sqlBuilder.toString().trim();
if (str.endsWith(removeSeparator)) {
// 如果以分割号结尾,则去除分割号
// 如果以分割号结尾,则去除分割号
str = str.substring(0, str.length() - 1);
}
if (str.trim().startsWith(removeSeparator)) {
@ -224,7 +224,7 @@ public class Util extends weaver.general.Util {
public static String removeSeparator(String string, String removeSeparator) {
String str = string.trim();
if (str.endsWith(removeSeparator)) {
// 如果以分割号结尾,则去除分割号
// 如果以分割号结尾,则去除分割号
str = str.substring(0, str.length() - 1);
}
if (str.trim().startsWith(removeSeparator)) {
@ -1212,8 +1212,8 @@ public class Util extends weaver.general.Util {
inputStream = new BufferedInputStream(new FileInputStream(path));
is = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
prop.load(is);
// Enumeration<?> enumeration = prop.propertyNames();
// 顺序读取
// Enumeration<?> enumeration = prop.propertyNames();
// 顺序读取
Enumeration<?> enumeration = prop.keys();
while (enumeration.hasMoreElements()) {
String key = (String) enumeration.nextElement();
@ -1256,7 +1256,7 @@ public class Util extends weaver.general.Util {
Pattern compile = Pattern.compile(objRegex);
Matcher matcher = compile.matcher(key);
if (matcher.find()) {
// 只匹配前缀.key=value模式的
// 只匹配前缀.key=value模式的
String resultKey = matcher.group("key");
preResult.put(resultKey, prop2MapPutValue(value));
}
@ -1264,7 +1264,7 @@ public class Util extends weaver.general.Util {
compile = Pattern.compile(moreKey);
matcher = compile.matcher(key);
if (matcher.find()) {
// 匹配前缀.key1.key2=value模式的
// 匹配前缀.key1.key2=value模式的
String objKey = matcher.group("objKey");
String prefixStr = prePrefix + "." + objKey;
Map<String, Object> valueMap;
@ -1282,11 +1282,11 @@ public class Util extends weaver.general.Util {
compile = Pattern.compile(strList);
matcher = compile.matcher(key);
if (matcher.find()) {
// 匹配前缀.key[0]=value模式的
// 匹配前缀.key[0]=value模式的
String objKey = matcher.group("key");
int index = Integer.parseInt(matcher.group("index"));
if (preResult.containsKey(objKey)) {
// 存在值
// 存在值
List<Object> valueList = (List<Object>) preResult.get(objKey);
if (index >= valueList.size()) {
valueList.add(prop2MapPutValue(value));
@ -1301,19 +1301,19 @@ public class Util extends weaver.general.Util {
return null;
}
String objArray = "^(" + prePrefix + "\\.)(?<arrKey>(\\w+))(\\[(?<index>([0-9])+)])\\.(?<objKey>(\\S)+)$";
// String objArray = "^("+prePrefix+"\\.)(?<arrKey>(\\w+))(\\[(?<index>([0-9])+)])(\\.(?<objKey>(\\S)+))+";
// String objArray = "^("+prePrefix+"\\.)(?<arrKey>(\\w+))(\\[(?<index>([0-9])+)])(\\.(?<objKey>(\\S)+))+";
compile = Pattern.compile(objArray);
matcher = compile.matcher(key);
if (matcher.find()) {
// 匹配前缀.key[0].name=value的模式
// 匹配前缀.key[0].name=value的模式
String arrKey = matcher.group("arrKey");
String objKey = matcher.group("objKey");
int index = Integer.parseInt(matcher.group("index"));
List<Map<String, Object>> mapList;
if (preResult.containsKey(arrKey)) {
// 存在
// 存在
mapList = (List<Map<String, Object>>) preResult.get(arrKey);
// mapList
// mapList
Map<String, Object> valueMap;
if (index >= mapList.size()) {
valueMap = new HashMap<>();
@ -1346,7 +1346,7 @@ public class Util extends weaver.general.Util {
int arrMoreIndex = Integer.parseInt(arrMoreKeyMatcher.group("index"));
List<Object> arrMoreListValue;
if (valueMap.containsKey(arrMoreArrKey)) {
// 存在值
// 存在值
arrMoreListValue = (List<Object>) valueMap.get(arrMoreArrKey);
if (arrMoreIndex >= arrMoreListValue.size()) {
arrMoreListValue.add(prop2MapPutValue(value));
@ -1361,11 +1361,11 @@ public class Util extends weaver.general.Util {
return null;
}
// 直接添加
// 直接添加
valueMap.put(objKey, prop2MapPutValue(value));
return null;
}
// 不存在
// 不存在
mapList = new ArrayList<>();
Map<String, Object> valueMap = new HashMap<>();
valueMap.put(objKey, prop2MapPutValue(value));
@ -1494,7 +1494,7 @@ public class Util extends weaver.general.Util {
//
private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
Map<Object, Boolean> seen = new ConcurrentHashMap<>();
// putIfAbsent添加不存在的键返回null如果为null表示不重复
// putIfAbsent添加不存在的键返回null如果为null表示不重复
return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}
@ -1585,7 +1585,7 @@ public class Util extends weaver.general.Util {
for (int i = 0; i < inputList.size(); i++) {
T item = inputList.get(i);
if (item instanceof InputStream) {
// 属于单级文件,直接压缩并返回
// 属于单级文件,直接压缩并返回
try {
zipOut.putNextEntry(new ZipEntry(base + i));
} catch (IOException e) {
@ -1618,7 +1618,7 @@ public class Util extends weaver.general.Util {
if (item instanceof ListZipEntity) {
ListZipEntity listZipEntity = (ListZipEntity) item;
if (listZipEntity.isDirectory()) {
// 表示属于文件夹,循环添加处理文件夹
// 表示属于文件夹,循环添加处理文件夹
handlerDirectory(listZipEntity.getFileList(), zipOut, base + listZipEntity.getDirectory() + File.separator);
} else {
List<AInputStream> aInputStreams = listZipEntity.getaInputStreamList();
@ -1649,7 +1649,7 @@ public class Util extends weaver.general.Util {
int catchLen = 10 * 1024;
for (ListZipEntity listZipEntity : fileList) {
if (listZipEntity.isDirectory()) {
// 如果是文件夹
// 如果是文件夹
handlerDirectory(listZipEntity.getFileList(), zipOut, base + listZipEntity.getDirectory() + File.separator);
} else {
List<AInputStream> aInputStreams = listZipEntity.getaInputStreamList();
@ -1759,8 +1759,8 @@ public class Util extends weaver.general.Util {
@Deprecated
public static String getDocCategorysById(String workflowId, String docFieldId) {
RecordSet rs = new RecordSet();
// rs.executeQuery("select formid from workflow_base where id = ?",workflowId);
// String formId = Util.recordeSet2Entity(rs, String.class);
// rs.executeQuery("select formid from workflow_base where id = ?",workflowId);
// String formId = Util.recordeSet2Entity(rs, String.class);
String query = "select doccategory from workflow_fileupload where workflowid = ? and fieldid = ?";
rs.executeQuery(query, workflowId, docFieldId);
String docCategorys = Util.null2String(Util.recordeSet2Entity(rs, String.class));
@ -2303,7 +2303,7 @@ public class Util extends weaver.general.Util {
continue;
}
dataMap.put(id, item);
// 判断是否属于根节点,如果是根节点,则将数据添加到树中
// 判断是否属于根节点,如果是根节点,则将数据添加到树中
if (predicate.test(parentId)) {
if (childMap.containsKey(id)) {
continue;
@ -2311,29 +2311,29 @@ public class Util extends weaver.general.Util {
treeList.add(item);
childMap.put(id, item);
} else {
// 如果不是根节点则通过id查找到父级
// 如果不是根节点则通过id查找到父级
T parent = dataMap.get(parentId);
if (Objects.isNull(parent)) {
// 如果父级为空,则说明他的父级还没有遍历到,需要从之后的数据进行遍历,直到找到父级为止
// 如果父级为空,则说明他的父级还没有遍历到,需要从之后的数据进行遍历,直到找到父级为止
List<T> list = buildTree(dataList, dataMap, childMap, index, getIdFn, getParentId, setChildFn, predicate);
parent = dataMap.get(parentId);
if (Objects.isNull(parent)) {
// 如果还是没有查询到父节点,则表明是顶层节点,将他添加到顶层节点中
// 如果还是没有查询到父节点,则表明是顶层节点,将他添加到顶层节点中
treeList.add(item);
} else {
// 如果找到了父节点,则将自己挂到父节点上
// 如果找到了父节点,则将自己挂到父节点上
if (childMap.containsKey(id)) {
continue;
}
setChildFn.accept(parent, item);
childMap.put(id, item);
}
// 如果查找的list不为空并且有值那就说明属于根节点
// 如果查找的list不为空并且有值那就说明属于根节点
if (list != null && list.size() > 0) {
treeList.addAll(list);
}
} else {
// 如果找到了父节点,则将自己挂到父节点上
// 如果找到了父节点,则将自己挂到父节点上
if (childMap.containsKey(id)) {
continue;
}
@ -2375,7 +2375,7 @@ public class Util extends weaver.general.Util {
continue;
}
dataMap.put(id, item);
// 判断是否属于根节点,如果是根节点,则将数据添加到树中
// 判断是否属于根节点,如果是根节点,则将数据添加到树中
if (predicate.test(parentId)) {
if (childMap.containsKey(id)) {
continue;
@ -2383,17 +2383,17 @@ public class Util extends weaver.general.Util {
treeList.add(item);
childMap.put(id, item);
} else {
// 如果不是根节点则通过id查找到父级
// 如果不是根节点则通过id查找到父级
T parent = dataMap.get(parentId);
if (Objects.isNull(parent)) {
// 如果父级为空,则说明他的父级还没有遍历到,需要从之后的数据进行遍历,直到找到父级为止
// 如果父级为空,则说明他的父级还没有遍历到,需要从之后的数据进行遍历,直到找到父级为止
List<T> list = buildTree(dataList, dataMap, childMap, index, getIdFn, getParentId, getChildFn, setChildFn, predicate);
parent = dataMap.get(parentId);
if (Objects.isNull(parent)) {
// 如果还是没有查询到父节点,则表明是顶层节点,将他添加到顶层节点中
// 如果还是没有查询到父节点,则表明是顶层节点,将他添加到顶层节点中
treeList.add(item);
} else {
// 如果找到了父节点,则将自己挂到父节点上
// 如果找到了父节点,则将自己挂到父节点上
if (childMap.containsKey(id)) {
continue;
}
@ -2402,12 +2402,12 @@ public class Util extends weaver.general.Util {
setChildFn.accept(parent, childList);
childMap.put(id, item);
}
// 如果查找的list不为空并且有值那就说明属于根节点
// 如果查找的list不为空并且有值那就说明属于根节点
if (list != null && list.size() > 0) {
treeList.addAll(list);
}
} else {
// 如果找到了父节点,则将自己挂到父节点上
// 如果找到了父节点,则将自己挂到父节点上
if (childMap.containsKey(id)) {
continue;
}
@ -2468,7 +2468,7 @@ public class Util extends weaver.general.Util {
throw new RuntimeException("invoke method err, cant not invoke method set" + name.substring(0, 1).toUpperCase() + name.substring(1));
}
}
// TODO 复制bean
// TODO 复制bean
return target;
}
@ -3229,7 +3229,7 @@ public class Util extends weaver.general.Util {
action = cronJobClass.newInstance();
if (declaredFields.length > 0) {
for (Field declaredField : declaredFields) {
// 必填参数验证
// 必填参数验证
boolean hasRequiredMark = declaredField.isAnnotationPresent(RequiredMark.class);
String name = declaredField.getName();
String setMethodName = getSetMethodName(name);
@ -3310,7 +3310,7 @@ public class Util extends weaver.general.Util {
action = actionClass.newInstance();
if (declaredFields.length > 0) {
for (Field declaredField : declaredFields) {
// 必填参数验证
// 必填参数验证
boolean hasRequiredMark = declaredField.isAnnotationPresent(RequiredMark.class);
String name = declaredField.getName();
String setMethodName = getSetMethodName(name);
@ -3458,10 +3458,12 @@ public class Util extends weaver.general.Util {
value:#sql{select workcode from hrmresource where id = #{main.zd1} and test = #{h-hah} and a in (${hrmids})}
key:hah
value:haode*/
// 最终通过反射调用weaver.aiyh_jitu.pushdata.service.GetAssignProcessorProcessorImpl类将参数传递给这个类
// String pattern = "&?(?<key>([#.\\w\\u4E00-\\u9FA5]+))=(?<value>((#(\\{|sql\\{))?([()\\-$#={ }.\\w\\u4E00-\\u9FA5?]+)?}?))&?";
// 最终通过反射调用weaver.aiyh_jitu.pushdata.service.GetAssignProcessorProcessorImpl类将参数传递给这个类
//String pattern = "&?(?<key>([#.\\w\\u4E00-\\u9FA5]+))=" +
// "(?<value>(`([\\s():/\\t\\-&*'?$#={ }.\\w\\u4E00-\\u9FA5]*)`|" +
// "((#(\\{|sql\\{))?([():/\\-$#={ }.\\w\\u4E00-\\u9FA5?]+)?}?)))&?";
String pattern = "&?(?<key>([#.\\w\\u4E00-\\u9FA5]+))=" +
"(?<value>((`([():/\\-&?$#={ }.\\w\\u4E00-\\u9FA5?]*)`)|" +
"(?<value>(`([^`]*)`|" +
"((#(\\{|sql\\{))?([():/\\-$#={ }.\\w\\u4E00-\\u9FA5?]+)?}?)))&?";
Pattern compile = Pattern.compile(pattern);
Matcher matcher = compile.matcher(paramStr);
@ -3470,6 +3472,9 @@ public class Util extends weaver.general.Util {
while (matcher.find()) {
String key = matcher.group("key");
String paramValue = matcher.group("value");
if (paramValue.startsWith("`") && paramValue.endsWith("`")) {
paramValue = paramValue.substring(1, paramValue.length() - 1);
}
pathParamMap.put(key, paramValue);
}
return pathParamMap;

View File

@ -0,0 +1,27 @@
package aiyh.utils.lock;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
/**
* <h1></h1>
*
* <p>create: 2022-12-11 02:07</p>
*
* @author youHong.ai
*/
@Getter
@Setter
@ToString
public class LockEntity {
/** 锁住次数 */
private Integer times;
/** 锁标识 */
private Thread lockMark;
/** 过期时间 */
private Long expirationTime;
}

View File

@ -0,0 +1,33 @@
package aiyh.utils.lock;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
/**
* <h1></h1>
*
* <p>create: 2022-12-11 00:24</p>
*
* @author youHong.ai
*/
@Setter
@Getter
@ToString
public class LockPojo {
/**
* id
*/
private Integer id;
/** 过期时间 */
private Long expirationTime;
/** 锁的键 */
private String lockName;
/** 锁状态 */
private Integer lockStatus;
}

View File

@ -0,0 +1,129 @@
package aiyh.utils.lock;
import aiyh.utils.annotation.recordset.ParamMapper;
import aiyh.utils.annotation.recordset.Select;
import aiyh.utils.annotation.recordset.SqlMapper;
import aiyh.utils.annotation.recordset.Update;
/**
* <h1></h1>
*
* <p>create: 2022-12-11 00:22</p>
*
* @author youHong.ai
*/
@SqlMapper
public interface LockUtilMapper {
/**
* <h2></h2>
* <i>2022/12/11 00:37</i>
* ******************************************
*
* @param lockKey
* @return LockPojo
* @author youHong.ai ******************************************
*/
@Select("select id, lock_name, lock_status, expiration_time " +
"from uf_cus_lock " +
"where lock_name = #{lockKey}")
LockPojo selectLock(@ParamMapper("lockKey") String lockKey);
/**
* <h2></h2>
* <i>2022/12/11 00:46</i>
* ******************************************
*
* @param id id
* @return boolean
* @author youHong.ai ******************************************
*/
@Update("update uf_cus_lock " +
"set lock_status = 0 " +
"where id = #{id} " +
" and lock_status = 1")
boolean unLock(@ParamMapper("id") Integer id);
/**
* <h2></h2>
* <i>2022/12/11 00:46</i>
* ******************************************
*
* @param lockKey
* @return boolean
* @author youHong.ai ******************************************
*/
@Update("update uf_cus_lock " +
"set lock_status = 0 " +
"where lock_name = #{lockKey} " +
" and lock_status = 1")
boolean unLock(@ParamMapper("lockKey") String lockKey);
/**
* <h2></h2>
* <i>2022/12/11 00:49</i>
* ******************************************
*
* @param id id
* @param lockKey
* @param time
* @return boolean
* @author youHong.ai ******************************************
*/
@Update("update uf_cus_lock " +
"set lock_name = #{lockKey}," +
" expiration_time = #{time}," +
" lock_status = 1 " +
"where id = #{id} " +
" and (lock_status = 0 or expiration_time < #{time})")
boolean lock(@ParamMapper("id") Integer id,
@ParamMapper("lockKey") String lockKey,
@ParamMapper("time") Long time);
/**
* <h2></h2>
* <i>2022/12/11 00:52</i>
* ******************************************
*
* @param lockKey
* @param time
* @return boolean
* @author youHong.ai ******************************************
*/
@Update("update uf_cus_lock " +
"set expiration_time = #{time} " +
"where lock_name = #{lockKey} " +
" and lock_status = 1")
boolean updateLockTime(@ParamMapper("lockKey") String lockKey,
@ParamMapper("time") Long time);
/**
* <h2></h2>
* <i>2022/12/11 15:02</i>
* ******************************************
*
* @param id id
* @param lockKey
* @param time
* @param expirationTime
* @return boolean
* @author youHong.ai ******************************************
*/
@Update("update uf_cus_lock " +
"set lock_name = #{lockKey}, " +
" expiration_time = #{time}, " +
" lock_status = 1 " +
"where id = #{id} " +
" and lock_status = 1 " +
" and expiration_time = #{expirationTime}")
boolean reLock(@ParamMapper("id") Integer id,
@ParamMapper("lockKey") String lockKey,
@ParamMapper("time") Long time,
@ParamMapper("expirationTime") Long expirationTime);
}

View File

@ -0,0 +1,346 @@
package aiyh.utils.lock;
import aiyh.utils.Util;
import aiyh.utils.excention.CustomerException;
import cn.hutool.core.thread.ThreadUtil;
import ebu7common.youhong.ai.bean.Builder;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
* <h1></h1>
*
* <p>create: 2022-12-11 00:21</p>
*
* @author youHong.ai
*/
public class LockUtils {
private static final LockUtilMapper mapper = Util.getMapper(LockUtilMapper.class);
private static final Map<String, LockEntity> LOCK_MAP = new HashMap<>();
/** 默认过期时间 10s */
private static final Long DEFAULT_OVERDUE_TIME = 1_000 * 10L;
private static final String UF_CUS_LOCK = "uf_cus_lock";
/**
* <h2></h2>
* <i>2022/12/11 15:40</i>
* ******************************************
*
* @param lockName
* @param reentrant
* @return boolean
* @author youHong.ai ******************************************
*/
public static boolean lock(String lockName, boolean reentrant) {
return lock(lockName, DEFAULT_OVERDUE_TIME, reentrant);
}
/**
* <h2></h2>
* <i>2022/12/11 15:40</i>
* ******************************************
*
* @param lockName
* @param overdueTime
* @param reentrant
* @return boolean
* @author youHong.ai ******************************************
*/
public static boolean lock(String lockName, Long overdueTime, boolean reentrant) {
LockPojo lockPojo = mapper.selectLock(lockName);
if (Objects.isNull(lockPojo) || lockPojo.getId() <= 0) {
return insertLock(lockName, overdueTime);
} else {
// 存在当前的锁的锁名称
if (lockPojo.getLockStatus() == 1) {
// 锁处于锁定状态
return onLock(lockName, overdueTime, reentrant, lockPojo);
} else {
// 处于未锁定状态开始对资源上锁
boolean lock = mapper.lock(lockPojo.getId(), lockName, overdueTime);
if (lock) {
// 锁定成功
LOCK_MAP.put(lockName,
Builder.builder(LockEntity::new)
.with(LockEntity::setTimes, 1)
.with(LockEntity::setLockMark, Thread.currentThread())
.with(LockEntity::setExpirationTime, overdueTime)
.build());
return true;
} else {
// 抢占锁失败
lockPojo = mapper.selectLock(lockName);
return retryGetLock(lockName, overdueTime, lockPojo);
}
}
}
}
/**
* <h2></h2>
* <i>2022/12/11 12:23</i>
* ******************************************
*
* @param lockName
* @param overdueTime
* @param reentrant
* @param lockPojo
* @return boolean
* @author youHong.ai ******************************************
*/
private static boolean onLock(String lockName, Long overdueTime, boolean reentrant, LockPojo lockPojo) {
Long time = lockPojo.getExpirationTime();
if (time > System.currentTimeMillis()) {
// 锁过期了 如果要使锁生效就将日期加长
return lockExpiration(lockName, overdueTime, lockPojo);
} else {
//锁没有过期
return inLockTime(lockName, overdueTime, reentrant);
}
}
/**
* <h2></h2>
* <i>2022/12/11 12:24</i>
* ******************************************
*
* @param lockName
* @param overdueTime
* @param reentrant
* @return boolean
* @author youHong.ai ******************************************
*/
private static boolean inLockTime(String lockName, Long overdueTime, boolean reentrant) {
//判断是否存在本地锁对象中
LockPojo lockPojo = mapper.selectLock(lockName);
if (!LOCK_MAP.containsKey(lockName)) {
// 不是本地锁,不支持可重入,使线程进入等待状态
int n = 0;
return retryGetLock(lockName, overdueTime, lockPojo);
}
// 是本地锁
return getLock(lockName, overdueTime, reentrant);
}
/**
* <h2></h2>
* <i>2022/12/11 15:34</i>
* ******************************************
*
* @param lockName
* @param overdueTime
* @param lockPojo
* @return boolean
* @author youHong.ai ******************************************
*/
private static boolean retryGetLock(String lockName, Long overdueTime, LockPojo lockPojo) {
while (lockPojo.getExpirationTime() > System.currentTimeMillis()) {
// 锁还没过期,使线程休眠
long l = lockPojo.getExpirationTime() - System.currentTimeMillis();
if (l > 10) {
ThreadUtil.safeSleep(l - 10L);
}
// 尝试获取锁
lockExpiration(lockName, overdueTime + l, lockPojo);
}
return true;
}
/**
* <h2></h2>
* <i>2022/12/11 13:57</i>
* ******************************************
*
* @param lockName
* @param overdueTime
* @param reentrant
* @return boolean
* @author youHong.ai ******************************************
*/
private static boolean getLock(String lockName, Long overdueTime, boolean reentrant) {
if (reentrant) {
LockEntity lockEntity = LOCK_MAP.get(lockName);
lockEntity.setTimes(lockEntity.getTimes() + 1);
} else {
LockPojo lockPojo = mapper.selectLock(lockName);
retryGetLock(lockName, overdueTime, lockPojo);
}
return true;
}
/**
* <h2></h2>
* <i>2022/12/11 12:25</i>
* ******************************************
*
* @param lockName
* @param overdueTime
* @return boolean
* @author youHong.ai ******************************************
*/
private static boolean lockExpiration(String lockName, Long overdueTime, LockPojo lockPojo) {
boolean lock = mapper.reLock(lockPojo.getId(), lockName, overdueTime, lockPojo.getExpirationTime());
if (lock) {
//更新锁状态成功
LockEntity lockEntity = Builder.builder(LockEntity::new)
.with(LockEntity::setTimes, 1)
.with(LockEntity::setLockMark, Thread.currentThread())
.with(LockEntity::setExpirationTime, overdueTime)
.build();
LOCK_MAP.put(lockName, lockEntity);
return true;
} else {
// 更新失败,可能是其他服务器抢先获得了锁
LockPojo newLockPojo = mapper.selectLock(lockName);
if (Objects.isNull(newLockPojo)) {
// 锁被释放了
boolean isLock = insertLock(lockName, overdueTime);
if (!isLock) {
throw new CustomerException("can not getLock!");
}
return true;
}
if (newLockPojo.getExpirationTime() > lockPojo.getExpirationTime()) {
// 锁被其他机器抢占
return retryGetLock(lockName, overdueTime, newLockPojo);
}
}
return false;
}
/**
* <h2></h2>
* <i>2022/12/11 12:25</i>
* ******************************************
*
* @param lockName
* @param overdueTime
* @return boolean
* @author youHong.ai ******************************************
*/
private static boolean insertLock(String lockName, Long overdueTime) {
// 没有锁需要新增一条锁记录
String modeId = Util.getModeIdByTableName(UF_CUS_LOCK);
int dataId = Util.getModeDataId(UF_CUS_LOCK, Integer.parseInt(modeId), 1);
long currentTime = System.currentTimeMillis();
Long expirationTime = currentTime + overdueTime;
boolean lock = mapper.lock(dataId, lockName, expirationTime);
if (lock) {
// 锁成功
LockEntity lockEntity = Builder.builder(LockEntity::new)
.with(LockEntity::setTimes, 1)
.with(LockEntity::setLockMark, Thread.currentThread())
.with(LockEntity::setExpirationTime, overdueTime)
.build();
LOCK_MAP.put(lockName, lockEntity);
} else {
// 锁失败
retryLock(dataId, lockName, expirationTime, 0);
}
return true;
}
/**
* <h2></h2>
* <i>2022/12/11 01:39</i>
* ******************************************
*
* @param dataId id
* @param lockName
* @param expirationTime
* @param n
* @author youHong.ai ******************************************
*/
private static void retryLock(int dataId, String lockName, Long expirationTime, int n) {
if (n > 5) {
throw new CustomerException("get lock error! 5 failed attempts to update the database");
}
ThreadUtil.safeSleep((n + 1) * 500);
boolean lock = mapper.lock(dataId, lockName, expirationTime + (n + 1) * 500L);
if (lock) {
// 锁成功
LockEntity lockEntity = Builder.builder(LockEntity::new)
.with(LockEntity::setTimes, 1)
.with(LockEntity::setLockMark, Thread.currentThread())
.with(LockEntity::setExpirationTime, expirationTime + (1 + n) * 500L)
.build();
LOCK_MAP.put(lockName, lockEntity);
} else {
// 锁失败
retryLock(dataId, lockName, expirationTime, n + 1);
}
}
/**
* <h2></h2>
* <i>2022/12/11 15:49</i>
* ******************************************
*
* @param lockKey
* @param expirationTime
* @return boolean
* @author youHong.ai ******************************************
*/
public boolean updateLockTime(String lockKey, Long expirationTime) {
if (!mapper.updateLockTime(lockKey, expirationTime)) {
// 更新失败
int n = 0;
do {
if (n++ > 5) {
return false;
}
} while (!mapper.updateLockTime(lockKey, expirationTime));
}
if (LOCK_MAP.containsKey(lockKey)) {
// 存在本地锁,更新锁信息
LockEntity lockEntity = LOCK_MAP.get(lockKey);
lockEntity.setExpirationTime(expirationTime);
}
return true;
}
/**
* <h2></h2>
* <i>2022/12/11 15:56</i>
* ******************************************
*
* @param lockName
* @author youHong.ai ******************************************
*/
public void unLock(String lockName) {
if (LOCK_MAP.containsKey(lockName)) {
// 存在本地锁
LockEntity lockEntity = LOCK_MAP.get(lockName);
if (!lockEntity.getLockMark().equals(Thread.currentThread())) {
// 并非当前上锁的线程在释放锁
return;
}
Integer times = lockEntity.getTimes();
if (times - 1 == 0) {
boolean unlock = mapper.unLock(lockName);
if (!unlock) {
int n = 0;
do {
if (n++ > 5) {
throw new CustomerException("can not unLock!Failed to release the lock after five attempts");
}
} while (!mapper.unLock(lockName)); // 释放锁失败
}
return;
}
lockEntity.setTimes(lockEntity.getTimes() - 1);
}
}
}

View File

@ -380,7 +380,7 @@ public class DealWithMapping extends ToolUtil {
List<Object> tempList = new ArrayList();
for (Object o : list) {
if (o instanceof Map) {
// map处理 key->1的类型
// map处理 key->1的类型
Map<String, Object> mapItem = (Map<String, Object>) o;
Map<String, List<ListMapIndexValue>> tempMap = new HashMap<>(8);
for (Map.Entry<String, Object> entry : mapItem.entrySet()) {
@ -426,11 +426,11 @@ public class DealWithMapping extends ToolUtil {
}
}
}
// tempList.addAll(list);
// tempList.addAll(list);
requestParam.put(paramName, tempList);
// if (!tempList.isEmpty()) {
// requestParam.put(paramName, tempList);
// }
// if (!tempList.isEmpty()) {
// requestParam.put(paramName, tempList);
// }
} else {
Object value = this.normalValueDeal(mainMap, detailMap, mappingDetail);
if (!Objects.isNull(value)) {
@ -471,7 +471,7 @@ public class DealWithMapping extends ToolUtil {
List<Object> tempList = new ArrayList();
for (Object o : list) {
if (o instanceof Map) {
// map处理
// map处理
Map<String, Object> mapItem = (Map<String, Object>) o;
Map<String, List<ListMapIndexValue>> tempMap = new HashMap<>(8);
for (Map.Entry<String, Object> entry : mapItem.entrySet()) {
@ -517,11 +517,11 @@ public class DealWithMapping extends ToolUtil {
}
}
}
// tempList.addAll(list);
// tempList.addAll(list);
requestParam.put(paramName, tempList);
// if (!tempList.isEmpty()) {
// requestParam.put(paramName, tempList);
// }
// if (!tempList.isEmpty()) {
// requestParam.put(paramName, tempList);
// }
} else {
Object value = this.normalValueDeal(mainMap, detailMap, relationRs, mappingDetail);
if (!Objects.isNull(value)) {
@ -618,7 +618,7 @@ public class DealWithMapping extends ToolUtil {
} else {
value = Util.null2String(mainMap.get("id"));
}
// value = Util.null2String(main.getString("id"));
// value = Util.null2String(main.getString("id"));
}
break;
// 随机数
@ -657,7 +657,7 @@ public class DealWithMapping extends ToolUtil {
}
return null;
}
// 自定义接口
// 自定义接口
case CUS_INTERFACE: {
if (null == valueContext || valueContext.length() == 0) {
} else {
@ -943,7 +943,7 @@ public class DealWithMapping extends ToolUtil {
}
return null;
}
// 自定义接口
// 自定义接口
case CUS_INTERFACE: {
if (null == valueContext || valueContext.length() == 0) {
} else {
@ -1124,10 +1124,10 @@ public class DealWithMapping extends ToolUtil {
list.add(o);
}
}
// for (MappingDetail mappingDetail : childList) {
// Object o = this.normalValueDeal(recordSet, null, mappingDetail);
// list.add(o);
// }
// for (MappingDetail mappingDetail : childList) {
// Object o = this.normalValueDeal(recordSet, null, mappingDetail);
// list.add(o);
// }
} else if ("2".equals(childSource)) {
// 自定义接口
Map<String, String> pathParamMap = new HashMap<>(8);
@ -1203,10 +1203,10 @@ public class DealWithMapping extends ToolUtil {
list.add(o);
}
}
// for (MappingDetail mappingDetail : childList) {
// Object o = this.normalValueDeal(recordSet, null, mappingDetail);
// list.add(o);
// }
// for (MappingDetail mappingDetail : childList) {
// Object o = this.normalValueDeal(recordSet, null, mappingDetail);
// list.add(o);
// }
} else if ("2".equals(childSource)) {
// 自定义接口
Map<String, String> pathParamMap = new HashMap<>(8);
@ -1241,8 +1241,9 @@ public class DealWithMapping extends ToolUtil {
/**
* <h2></h2>
*
* @param responseMappingList
* @param requestRes
* @param requestRes
* @return
*/
public Map<String, Map<String, Object>> dealResponse(List<ResponseMapping> responseMappingList, Map<String, Object> requestRes) {
@ -1374,9 +1375,9 @@ public class DealWithMapping extends ToolUtil {
value:#sql{select workcode from hrmresource where id = #{main.zd1} and test = #{h-hah} and a in (${hrmids})}
key:hah
value:haode*/
// 最终通过反射调用weaver.aiyh_jitu.pushdata.service.GetAssignProcessorProcessorImpl类将参数传递给这个类 使用``包裹的字符串会被解析为一个字符串
// 最终通过反射调用weaver.aiyh_jitu.pushdata.service.GetAssignProcessorProcessorImpl类将参数传递给这个类 使用``包裹的字符串会被解析为一个字符串
String pattern = "&?(?<key>([#.\\w\\u4E00-\\u9FA5]+))=" +
"(?<value>((`([():/\\-&$?#={ }.\\w\\u4E00-\\u9FA5?]*)`)|" +
"(?<value>((`([^`]*)`)|" +
"((#(\\{|sql\\{))?([():/\\-$#={ }.\\w\\u4E00-\\u9FA5?]+)?}?)))&?";
Pattern compile = Pattern.compile(pattern);
Matcher matcher = compile.matcher(paramStr);

View File

@ -1,5 +1,6 @@
package youhong.ai.pcn;
import aiyh.utils.Util;
import aiyh.utils.httpUtil.HttpMultipartFile;
import aiyh.utils.httpUtil.ResponeVo;
import aiyh.utils.httpUtil.util.HttpUtils;
@ -108,6 +109,21 @@ public class TestOrganization extends BaseTest {
@Test
public void testStaticLog() {
log.info("哈哈哈好的方式");
String testStr = "slflas.fasjdflaf.fasdf?hah=liuliu&cus=`select? * fr$%&#@!)(<>?/\\{}「」【【】[]~、asfom table where id = '' and teset = #{name}`&niua=卧槽";
Map<String, String> stringStringMap = Util.parseCusInterfacePathParam(testStr);
System.out.println(JSON.toJSONString(stringStringMap));
//String pattern = "&?(?<key>([#.\\w\\u4E00-\\u9FA5]+))=" +
// "(?<value>(`([():/\\-&$#='*{ }.\\w\\u4E00-\\u9FA5?]*)`|((#(\\{|sql\\{))?([():/\\-$#={ }.\\w\\u4E00-\\u9FA5?]+)?}?)))&?";
//String pattern = "=`(?<value>(([\\u4E00-\\u9FA5\\w.'#=?${ }*])*))`";
//String pattern = "&?(?<key>([#.\\w\\u4E00-\\u9FA5]+))=(?<value>(`([():/\\-&?%#\\t\\n='{ }.\\w\\u4E00-\\u9FA5]*)*`))";
//Pattern compile = Pattern.compile(pattern);
//Matcher matcher = compile.matcher(testStr);
//while (matcher.find()) {
// String key = matcher.group("key");
// System.out.println(key);
//String paramValue = matcher.group("value");
//System.out.println(paramValue);
//}
}