|
|
@@ -2052,6 +2052,58 @@ public class MESHelperServiceImpl implements MESHelperService {
|
|
|
return AE_MASTER.toString();
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 原子占用SN
|
|
|
+ * <p>
|
|
|
+ * 原实现是"先select符合条件的SN,再在循环里逐条update",两步之间没有互斥,两个请求时间接近时会读到
|
|
|
+ * 同一批msl_status=0的记录,从而返回相同的SN。
|
|
|
+ * 这里改成先占用再反查:
|
|
|
+ * 1)占用用单条update完成,where里带nvl(msl_status,0)=0。并发请求在行锁等待结束(Oracle会阻塞后重试该行)
|
|
|
+ * 会用当前数据重新评估该条件,已被占用的行会被跳过,因此同一行不会被占用两次;
|
|
|
+ * 2)占用时写入唯一token,再按token反查,精确得到本次占用的SN,不再依赖时间或行号;
|
|
|
+ * 3)占用不足时重新补占用,最终仍不足则归还本次已占用的行,避免占用泄漏。
|
|
|
+ *
|
|
|
+ * @param macode 工单号
|
|
|
+ * @param mType SN类型,传空表示不限类型
|
|
|
+ * @param need 需要占用的数量
|
|
|
+ * @return 本次占用的SN列表(每项含sn、id,按msl_sncode升序);数量不足时归还并返回null
|
|
|
+ */
|
|
|
+ private List<Map<String,String>> claimSnCodes(String macode,String mType,int need){
|
|
|
+ String typeCond=(mType==null||"".equals(mType))?"1=1":"nvl(msl_type,' ')='"+mType+"'";
|
|
|
+ String token=UUID.randomUUID().toString().replace("-","");
|
|
|
+ List<Map<String,String>> list=new ArrayList<>();
|
|
|
+ while(list.size()<need){
|
|
|
+ int updated=baseDao.executeUpdate("update MakeSnList set msl_status=-1,msl_signtime=sysdate,msl_mainbarcode='"+token+"' " +
|
|
|
+ "where nvl(msl_status,0)=0 and msl_id in (select msl_id from (select msl_id from MakeSnList " +
|
|
|
+ "where msl_makecode='"+macode+"' and "+typeCond+" and nvl(msl_status,0)=0 order by msl_sncode) where rownum<="+(need-list.size())+")");
|
|
|
+ if(updated<=0){
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ //token唯一,反查到的就是本次请求占用的行
|
|
|
+ SqlRowList rs=baseDao.queryForRowSet("select msl_sncode,msl_id from MakeSnList where msl_mainbarcode='"+token+"' and msl_status=-1 order by msl_sncode");
|
|
|
+ list.clear();
|
|
|
+ while(rs.next()){
|
|
|
+ Map<String,String> one=new HashMap<>();
|
|
|
+ one.put("sn",rs.getGeneralString("msl_sncode"));
|
|
|
+ one.put("id",rs.getGeneralString("msl_id"));
|
|
|
+ list.add(one);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(list.size()<need){
|
|
|
+ //可用数量不足,归还本次已占用的行
|
|
|
+ StringBuilder ids=new StringBuilder();
|
|
|
+ for(Map<String,String> one:list){
|
|
|
+ ids.append(one.get("id")).append(",");
|
|
|
+ }
|
|
|
+ if(ids.length()>0){
|
|
|
+ ids.append("0");
|
|
|
+ baseDao.execute("update MakeSnList set msl_status=0,msl_signtime=null,msl_mainbarcode='' where msl_id in ("+ids+")");
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public Map<Object,Object> getMESSnCode(String data) {
|
|
|
Map<String, Object> map=null;
|
|
|
@@ -2097,26 +2149,26 @@ public class MESHelperServiceImpl implements MESHelperService {
|
|
|
rmap.put("message","SN不足!");
|
|
|
return rmap;
|
|
|
}
|
|
|
- List<String> sqls = new ArrayList<>();
|
|
|
+ //原子占用SN,防止并发请求拿到相同的SN
|
|
|
+ List<Map<String,String>> claimed=claimSnCodes(macode,"",(int)Math.ceil(sncount));
|
|
|
+ if(claimed==null){
|
|
|
+ rmap.put("code",-1);
|
|
|
+ rmap.put("message","SN不足!");
|
|
|
+ return rmap;
|
|
|
+ }
|
|
|
List<Map<String, Object>> maps = new ArrayList<>();
|
|
|
- Map<String, Object> snmap=null;
|
|
|
- SqlRowList rs = baseDao.queryForRowSet("select msl_sncode,msl_id from (select msl_sncode,msl_id from MakeSnList where msl_makecode='" + macode + "' and nvl(msl_status,0)=0 order by msl_sncode) where rownum<="+sncount +" order by msl_sncode ");
|
|
|
- String mainbarcode="";
|
|
|
+ //主条码取排序后的最后一条
|
|
|
+ String mainbarcode=claimed.get(claimed.size()-1).get("sn");
|
|
|
String msl_id="";
|
|
|
- while (rs.next()){
|
|
|
- snmap=new HashMap<String, Object>();
|
|
|
- snmap.put("serialNo",rs.getGeneralString("msl_sncode"));
|
|
|
- mainbarcode=rs.getGeneralString("msl_sncode");
|
|
|
+ for(Map<String,String> one:claimed){
|
|
|
+ Map<String, Object> snmap=new HashMap<String, Object>();
|
|
|
+ snmap.put("serialNo",one.get("sn"));
|
|
|
maps.add(snmap);
|
|
|
- baseDao.execute("update MakeSnList set msl_signtime=sysdate,msl_status=-1 where msl_id="+rs.getGeneralInt("msl_id"));
|
|
|
- msl_id+=rs.getGeneralInt("msl_id")+",";
|
|
|
+ msl_id+=one.get("id")+",";
|
|
|
}
|
|
|
msl_id+="0";
|
|
|
baseDao.execute("update MakeSnList set msl_mainbarcode='"+mainbarcode+"' where msl_id in ("+msl_id+")");
|
|
|
|
|
|
-// if (sqls!=null&&sqls.size()>0){
|
|
|
-// baseDao.execute(sqls);
|
|
|
-// }
|
|
|
rmap.put("code",0);
|
|
|
rmap.put("data",maps);
|
|
|
return rmap;
|
|
|
@@ -2173,27 +2225,26 @@ public class MESHelperServiceImpl implements MESHelperService {
|
|
|
rmap.put("message","工单号"+macode+"SN不足!类型"+mType);
|
|
|
return rmap;
|
|
|
}
|
|
|
- List<String> sqls = new ArrayList<>();
|
|
|
+ //原子占用SN,防止并发请求拿到相同的SN
|
|
|
+ List<Map<String,String>> claimed=claimSnCodes(macode,mType,(int)Math.ceil(sncount));
|
|
|
+ if(claimed==null){
|
|
|
+ rmap.put("code",-1);
|
|
|
+ rmap.put("message","工单号"+macode+"SN不足!类型"+mType);
|
|
|
+ return rmap;
|
|
|
+ }
|
|
|
List<Map<String, Object>> maps = new ArrayList<>();
|
|
|
- Map<String, Object> snmap=null;
|
|
|
- SqlRowList rs = baseDao.queryForRowSet("select msl_sncode,msl_id from (select msl_sncode,msl_id from MakeSnList where msl_makecode='" + macode + "' and nvl(msl_type,' ')='"+mType+"' and nvl(msl_status,0)=0 order by msl_sncode) where rownum<="+sncount +" order by msl_sncode ");
|
|
|
- String mainbarcode="";
|
|
|
+ //主条码取排序后的最后一条
|
|
|
+ String mainbarcode=claimed.get(claimed.size()-1).get("sn");
|
|
|
String msl_id="";
|
|
|
- while (rs.next()){
|
|
|
- snmap=new HashMap<String, Object>();
|
|
|
- snmap.put("serialNo",rs.getGeneralString("msl_sncode"));
|
|
|
- mainbarcode=rs.getGeneralString("msl_sncode");
|
|
|
+ for(Map<String,String> one:claimed){
|
|
|
+ Map<String, Object> snmap=new HashMap<String, Object>();
|
|
|
+ snmap.put("serialNo",one.get("sn"));
|
|
|
maps.add(snmap);
|
|
|
- baseDao.execute("update MakeSnList set msl_signtime=sysdate,msl_status=-1 where msl_id="+rs.getGeneralInt("msl_id"));
|
|
|
- msl_id+=rs.getGeneralInt("msl_id")+",";
|
|
|
- baseDao.execute("insert into MACRELEASE(MR_ID,MR_SNCODE,MR_INDATE)values(MACRELEASE_seq.nextval,'"+mainbarcode+"',sysdate)");
|
|
|
+ baseDao.execute("insert into MACRELEASE(MR_ID,MR_SNCODE,MR_INDATE)values(MACRELEASE_seq.nextval,'"+one.get("sn")+"',sysdate)");
|
|
|
+ msl_id+=one.get("id")+",";
|
|
|
}
|
|
|
msl_id+="0";
|
|
|
baseDao.execute("update MakeSnList set msl_mainbarcode='"+mainbarcode+"' where msl_id in ("+msl_id+")");
|
|
|
-
|
|
|
-// if (sqls!=null&&sqls.size()>0){
|
|
|
-// baseDao.execute(sqls);
|
|
|
-// }
|
|
|
rmap.put("code",0);
|
|
|
rmap.put("data",maps);
|
|
|
return rmap;
|