网络互斥实现方案原创
金蝶云社区-兜兜丶
兜兜丶
0人赞赏了该文章 29次浏览 未经作者许可,禁止转载编辑于2024年07月17日 18:18:35
public class MutexControlUtil {

   public static final MutexControlUtil me = new MutexControlUtil();

   private static final Log logger = LogFactory.getLog(MutexControlUtil.class);


   /**
    * 释放锁
    * @param entityKey 单据标识
    * @param operKey 操作
    * @param pkids 单据ID
    * @return
    */
   public Boolean release(String entityKey, String operKey, List<Object> pkids){
       for(Object pkid : pkids){
           boolean val = MutexHelper.release(entityKey, operKey, pkid.toString());
           System.out.println("解锁:" + val);
       }
       return true;
   }


   /**
    * 批量释放锁
    * @param entityKey 单据标识
    * @param operKey 操作
    * @param pkids 单据ID
    * @return
    */
   public boolean batchRelease(String entityKey, String operKey, List<Object> pkids){

       try (DataMutex dataMutex = DataMutex.create()) {
           String groupId = "default_netctrl";
           List<Map<String, Object>> mutexRequireList = new ArrayList<>();

           for(Object id : pkids){
               Map<String, Object> requireParam = new HashMap<>();
               requireParam.put(DataMutex.PARAMNAME_DATAOBJID, String.valueOf(id));
               requireParam.put(DataMutex.PARAMNAME_GROUPID, groupId);
               requireParam.put(DataMutex.PARAMNAME_ENTITYKEY, entityKey);
               requireParam.put(DataMutex.PARAMNAME_OPERATIONKEY, operKey);
               mutexRequireList.add(requireParam);
           }

           Map<String, Boolean> mutexResult = dataMutex.batchRelease(mutexRequireList);

           // 分析网控申请结果
           for (Map.Entry<String, Boolean> mutexItem : mutexResult.entrySet()) {
               String objId = mutexItem.getKey();
               Boolean ret = mutexItem.getValue();

               if (ret) {
                   //申请互斥成功的
                   System.out.println("1111111");
               } else {
                   Map lockInfo = dataMutex.getLockInfo(objId, groupId, entityKey);
                   if (lockInfo != null) {
                       //提示锁信息
                       logger.info("释放锁失败,单据ID",objId);
                   }
               }
           }
       } catch (Exception e) {
           logger.error("释放锁失败,原因如下:", e.getMessage(), e);
       }

       return true;
   }

   /**
    * 批量互斥锁校验
    * @param entityId 单据标识
    * @param pkids 单据ID集合
    * @param opKey 操作
    * @param errMsg 错误信息
    * @return
    */
   public Boolean batchRequire(String entityId, List<Object> pkids, String opKey, StringBuilder errMsg){
       DynamicObjectCollection cols = QueryServiceHelper.query(entityId, "id,billno",
               new QFilter[]{new QFilter("id", "in", pkids)});
       Map<String,String> colMaps = Maps.newHashMap();
       for(DynamicObject dyn : cols){
           colMaps.put(dyn.getString("id"),dyn.getString("billno"));
       }

       Boolean result = true;

       List<Object> successList = Lists.newArrayList();

       try (DataMutex dataMutex = DataMutex.create()) {
           //申请网络互斥锁
           //如果需要和标准操作(如保存、提交、审核...)互斥,则可使用default_netctrl(默认分组),不需要和标准操作互斥则需要用自定义的groupId
           String groupId = "default_netctrl";
           String entityKey = entityId;
           List<Map<String, Object>> mutexRequireList = new ArrayList<>();

           for(Object id : pkids){
               Map<String, Object> requireParam = new HashMap<>();
               requireParam.put(DataMutex.PARAMNAME_DATAOBJID, String.valueOf(id));
               requireParam.put(DataMutex.PARAMNAME_DATA_OBJ_NUMBER, colMaps.get(id.toString()));
               requireParam.put(DataMutex.PARAMNAME_GROUPID, groupId);
               requireParam.put(DataMutex.PARAMNAME_ENTITYKEY, entityKey);
               requireParam.put(DataMutex.PARAMNAME_OPERATIONKEY, opKey);
               requireParam.put(DataMutex.PARAMNAME_ISSTRICT, true);
               //建议设置自定义标识,用于后续区分标准操作和自定义申请的网控
               requireParam.put(DataMutex.PARAMNAME_DATA_CALL_SOURCE, "missionWare");
               mutexRequireList.add(requireParam);
           }

           Map<String, Boolean> mutexResult = dataMutex.batchrequire(mutexRequireList);

           // 分析网控申请结果
           for (Map.Entry<String, Boolean> mutexItem : mutexResult.entrySet()) {
               String objId = mutexItem.getKey();
               Boolean ret = mutexItem.getValue();
               if (ret) {
                   //申请互斥成功的

                   System.out.println("111111");

                    successList.add(objId);

               } else {

                   result = false;
                   Map<String, String> lockInfo = dataMutex.getLockInfo(objId, groupId, entityKey);
                   if (lockInfo != null) {
                       //申请锁失败,提示已经存在的锁信息
                       String userName = "XXX";
                       if(StringUtils.isNotBlank(lockInfo.get("userid"))){
                           MainEntityType dt = EntityMetadataCache.getDataEntityType("bos_user");
                           long userId = Long.parseLong(lockInfo.get("userid"));
                           Map<Object, DynamicObject> cacheUserObjs = BusinessDataReader.loadFromCache(new Object[]{userId}, dt);
                           DynamicObject userObj = (DynamicObject)cacheUserObjs.get(userId);
                           if (userObj != null) {
                               userName = userObj.getString("name");
                           }
                       }
                       errMsg.append(String.format("当前单据{%s},已被{%s}打开!", colMaps.get(objId),userName));
                   }else {
                       errMsg.append(String.format("当前单据{%s},已被打开,请联系管理员!", colMaps.get(objId)));
                   }
               }
           }
       } catch (Exception e) {
           result = false;
           errMsg.append("当前程序异常,请联系管理员");
           logger.error("互斥锁失败,原因如下:", e.getMessage(), e);
       }


    
    if(!result && successList.size() > 0){
           MutexControlUtil.me.batchRelease(entityId,opKey,successList);
     }
       return result;
   }

   /**
    * 锁定 (局限:当前人已打开的数据,不会校验)
    * @param entityId 单据标识
    * @param pkids 单据ID集合
    * @param opKey 操作
    * @param errMsg 错误消息
    * @return
    */
   public Boolean require(String entityId, List<Object> pkids, String opKey, StringBuilder errMsg){
       StringBuilder msg = new StringBuilder();
       Boolean result = true;
       List<Object> successList = Lists.newArrayList();
       for(Object pkid : pkids){
           if(!MutexHelper.require(entityId, pkid, opKey, msg)){
               result = false; //失败
               errMsg.append(msg.toString());
           }else {
               successList.add(pkid);
           }
       }
       if(!result){
           //释放锁定成功的数据(因:会产生锁定数据)
           MutexControlUtil.me.release(entityId,opKey,successList);
       }
       return result;
   }

}

    

赞 0