From 2d4bce951376af73dec012398e4f7688ace48982 Mon Sep 17 00:00:00 2001 From: "youHong.ai" <774495953@qq.com> Date: Sun, 11 Dec 2022 16:51:14 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=86=E5=B8=83=E5=BC=8F=E9=9D=9E=E5=85=AC?= =?UTF-8?q?=E5=B9=B3=E9=94=81=E5=AE=9E=E7=8E=B0=E3=80=81=E8=B7=AF=E5=BE=84?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E6=AD=A3=E5=88=99=E8=A1=A8=E8=BE=BE=E5=BC=8F?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=A2=9E=E5=BC=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/aiyh/utils/Util.java | 89 ++--- src/main/java/aiyh/utils/lock/LockEntity.java | 27 ++ src/main/java/aiyh/utils/lock/LockPojo.java | 33 ++ .../java/aiyh/utils/lock/LockUtilMapper.java | 129 +++++++ src/main/java/aiyh/utils/lock/LockUtils.java | 346 ++++++++++++++++++ .../config/service/DealWithMapping.java | 49 +-- .../java/youhong/ai/pcn/TestOrganization.java | 16 + 7 files changed, 623 insertions(+), 66 deletions(-) create mode 100644 src/main/java/aiyh/utils/lock/LockEntity.java create mode 100644 src/main/java/aiyh/utils/lock/LockPojo.java create mode 100644 src/main/java/aiyh/utils/lock/LockUtilMapper.java create mode 100644 src/main/java/aiyh/utils/lock/LockUtils.java diff --git a/src/main/java/aiyh/utils/Util.java b/src/main/java/aiyh/utils/Util.java index e4891bc..7aec07b 100644 --- a/src/main/java/aiyh/utils/Util.java +++ b/src/main/java/aiyh/utils/Util.java @@ -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 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 valueList = (List) 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 + "\\.)(?(\\w+))(\\[(?([0-9])+)])\\.(?(\\S)+)$"; -// String objArray = "^("+prePrefix+"\\.)(?(\\w+))(\\[(?([0-9])+)])(\\.(?(\\S)+))+"; + // String objArray = "^("+prePrefix+"\\.)(?(\\w+))(\\[(?([0-9])+)])(\\.(?(\\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> mapList; if (preResult.containsKey(arrKey)) { -// 存在 + // 存在 mapList = (List>) preResult.get(arrKey); -// mapList + // mapList Map 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 arrMoreListValue; if (valueMap.containsKey(arrMoreArrKey)) { -// 存在值 + // 存在值 arrMoreListValue = (List) 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 valueMap = new HashMap<>(); valueMap.put(objKey, prop2MapPutValue(value)); @@ -1494,7 +1494,7 @@ public class Util extends weaver.general.Util { // private static Predicate distinctByKey(Function keyExtractor) { Map 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 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 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 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 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 = "&?(?([#.\\w\\u4E00-\\u9FA5]+))=(?((#(\\{|sql\\{))?([()\\-$#={ }.\\w\\u4E00-\\u9FA5?]+)?}?))&?"; + // 最终通过反射调用weaver.aiyh_jitu.pushdata.service.GetAssignProcessorProcessorImpl类,将参数传递给这个类, + //String pattern = "&?(?([#.\\w\\u4E00-\\u9FA5]+))=" + + // "(?(`([\\s():/\\t\\-&*'?$#={ }.\\w\\u4E00-\\u9FA5]*)`|" + + // "((#(\\{|sql\\{))?([():/\\-$#={ }.\\w\\u4E00-\\u9FA5?]+)?}?)))&?"; String pattern = "&?(?([#.\\w\\u4E00-\\u9FA5]+))=" + - "(?((`([():/\\-&?$#={ }.\\w\\u4E00-\\u9FA5?]*)`)|" + + "(?(`([^`]*)`|" + "((#(\\{|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; diff --git a/src/main/java/aiyh/utils/lock/LockEntity.java b/src/main/java/aiyh/utils/lock/LockEntity.java new file mode 100644 index 0000000..ba8f225 --- /dev/null +++ b/src/main/java/aiyh/utils/lock/LockEntity.java @@ -0,0 +1,27 @@ +package aiyh.utils.lock; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +/** + *

锁参数信息

+ * + *

create: 2022-12-11 02:07

+ * + * @author youHong.ai + */ + +@Getter +@Setter +@ToString +public class LockEntity { + /** 锁住次数 */ + private Integer times; + + /** 锁标识 */ + private Thread lockMark; + + /** 过期时间 */ + private Long expirationTime; +} diff --git a/src/main/java/aiyh/utils/lock/LockPojo.java b/src/main/java/aiyh/utils/lock/LockPojo.java new file mode 100644 index 0000000..d1cc18b --- /dev/null +++ b/src/main/java/aiyh/utils/lock/LockPojo.java @@ -0,0 +1,33 @@ +package aiyh.utils.lock; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +/** + *

锁对应数据库的实体类

+ * + *

create: 2022-12-11 00:24

+ * + * @author youHong.ai + */ + +@Setter +@Getter +@ToString +public class LockPojo { + /** + * 数据库id + */ + private Integer id; + + /** 过期时间 */ + private Long expirationTime; + + /** 锁的键 */ + private String lockName; + + /** 锁状态 */ + private Integer lockStatus; + +} diff --git a/src/main/java/aiyh/utils/lock/LockUtilMapper.java b/src/main/java/aiyh/utils/lock/LockUtilMapper.java new file mode 100644 index 0000000..3cd6a86 --- /dev/null +++ b/src/main/java/aiyh/utils/lock/LockUtilMapper.java @@ -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; + +/** + *

分布式锁数据库查询

+ * + *

create: 2022-12-11 00:22

+ * + * @author youHong.ai + */ + +@SqlMapper +public interface LockUtilMapper { + + + /** + *

根据锁名称获取锁状态

+ * 2022/12/11 00:37 + * ****************************************** + * + * @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); + + + /** + *

根据锁名称释放锁资源

+ * 2022/12/11 00:46 + * ****************************************** + * + * @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); + + /** + *

根据锁名称释放锁资源

+ * 2022/12/11 00:46 + * ****************************************** + * + * @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); + + + /** + *

更新锁状态,锁住资源

+ * 2022/12/11 00:49 + * ****************************************** + * + * @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); + + + /** + *

更新锁过期时间,续期

+ * 2022/12/11 00:52 + * ****************************************** + * + * @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); + + + /** + *

对过期锁重新设置锁

+ * 2022/12/11 15:02 + * ****************************************** + * + * @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); +} diff --git a/src/main/java/aiyh/utils/lock/LockUtils.java b/src/main/java/aiyh/utils/lock/LockUtils.java new file mode 100644 index 0000000..487189a --- /dev/null +++ b/src/main/java/aiyh/utils/lock/LockUtils.java @@ -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; + +/** + *

分布式锁

+ * + *

create: 2022-12-11 00:21

+ * + * @author youHong.ai + */ + +public class LockUtils { + + private static final LockUtilMapper mapper = Util.getMapper(LockUtilMapper.class); + + private static final Map 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"; + + /** + *

上锁

+ * 2022/12/11 15:40 + * ****************************************** + * + * @param lockName 锁名称 + * @param reentrant 是否可重入 + * @return boolean 是否抢占成功 + * @author youHong.ai ****************************************** + */ + public static boolean lock(String lockName, boolean reentrant) { + return lock(lockName, DEFAULT_OVERDUE_TIME, reentrant); + } + + + /** + *

上锁

+ * 2022/12/11 15:40 + * ****************************************** + * + * @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); + } + } + } + } + + /** + *

处于锁状态

+ * 2022/12/11 12:23 + * ****************************************** + * + * @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); + } + } + + /** + *

锁未过期

+ * 2022/12/11 12:24 + * ****************************************** + * + * @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); + } + + /** + *

尝试抢占资源锁

+ * 2022/12/11 15:34 + * ****************************************** + * + * @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; + } + + /** + *

获取锁

+ * 2022/12/11 13:57 + * ****************************************** + * + * @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; + } + + /** + *

锁过期

+ * 2022/12/11 12:25 + * ****************************************** + * + * @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; + } + + /** + *

新增锁记录

+ * 2022/12/11 12:25 + * ****************************************** + * + * @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; + } + + + /** + *

重试锁

+ * 2022/12/11 01:39 + * ****************************************** + * + * @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); + } + } + + + /** + *

锁续期

+ * 2022/12/11 15:49 + * ****************************************** + * + * @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; + } + + + /** + *

释放锁

+ * 2022/12/11 15:56 + * ****************************************** + * + * @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); + } + } +} + diff --git a/src/main/java/weaver/xiao/commons/config/service/DealWithMapping.java b/src/main/java/weaver/xiao/commons/config/service/DealWithMapping.java index 0217882..14c5946 100644 --- a/src/main/java/weaver/xiao/commons/config/service/DealWithMapping.java +++ b/src/main/java/weaver/xiao/commons/config/service/DealWithMapping.java @@ -380,7 +380,7 @@ public class DealWithMapping extends ToolUtil { List tempList = new ArrayList(); for (Object o : list) { if (o instanceof Map) { -// map处理 key->1的类型 + // map处理 key->1的类型 Map mapItem = (Map) o; Map> tempMap = new HashMap<>(8); for (Map.Entry 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 tempList = new ArrayList(); for (Object o : list) { if (o instanceof Map) { -// map处理 + // map处理 Map mapItem = (Map) o; Map> tempMap = new HashMap<>(8); for (Map.Entry 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 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 pathParamMap = new HashMap<>(8); @@ -1241,8 +1241,9 @@ public class DealWithMapping extends ToolUtil { /** *

请求结果赋值到配置信息中

+ * * @param responseMappingList 回写信息配置列表 - * @param requestRes 请求结果 + * @param requestRes 请求结果 * @return 要插入的信息 */ public Map> dealResponse(List responseMappingList, Map 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 = "&?(?([#.\\w\\u4E00-\\u9FA5]+))=" + - "(?((`([():/\\-&$?#={ }.\\w\\u4E00-\\u9FA5?]*)`)|" + + "(?((`([^`]*)`)|" + "((#(\\{|sql\\{))?([():/\\-$#={ }.\\w\\u4E00-\\u9FA5?]+)?}?)))&?"; Pattern compile = Pattern.compile(pattern); Matcher matcher = compile.matcher(paramStr); diff --git a/src/test/java/youhong/ai/pcn/TestOrganization.java b/src/test/java/youhong/ai/pcn/TestOrganization.java index 321c7a8..cae7065 100644 --- a/src/test/java/youhong/ai/pcn/TestOrganization.java +++ b/src/test/java/youhong/ai/pcn/TestOrganization.java @@ -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 stringStringMap = Util.parseCusInterfacePathParam(testStr); + System.out.println(JSON.toJSONString(stringStringMap)); + //String pattern = "&?(?([#.\\w\\u4E00-\\u9FA5]+))=" + + // "(?(`([():/\\-&$#='*{ }.\\w\\u4E00-\\u9FA5?]*)`|((#(\\{|sql\\{))?([():/\\-$#={ }.\\w\\u4E00-\\u9FA5?]+)?}?)))&?"; + //String pattern = "=`(?(([\\u4E00-\\u9FA5\\w.'#=?${ }*])*))`"; + //String pattern = "&?(?([#.\\w\\u4E00-\\u9FA5]+))=(?(`([():/\\-&?%#\\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); + //} }