chen.llin
2 天以前 2ea1c479596a2b5417319de0d230d79040491c0a
修复bug-深库位出库,浅库位有货时卡住并且锁表的情况
2个文件已修改
70 ■■■■ 已修改文件
src/main/java/com/zy/core/thread/SiemensCrnThread.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/service/impl/MainServiceImpl.java 61 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/SiemensCrnThread.java
@@ -208,6 +208,9 @@
                        crnCommand.setAckFinish((short)1);
                        if (write(crnCommand)) {
                            resetFlag = false;
                            News.info("{}号堆垛机,任务{}完成确认信号发送成功",crnProtocol.getCrnNo(),crnProtocol.getTaskNo());
                        } else {
                            News.error("{}号堆垛机,任务{}完成确认信号发送失败",crnProtocol.getCrnNo(),crnProtocol.getTaskNo());
                        }
                    }
                }
@@ -262,7 +265,7 @@
        command.setCrnNo(slave.getId());
//        short[] array = new short[10];
        short[] array = new short[10];
        array[0] = command.getAckFinish(); // 任务完成确认位
        array[1] = command.getTaskNo();  // 任务号
@@ -278,7 +281,6 @@
        OperateResult result = siemensNet.Write("DB100.0", array);
        News.info("堆垛机命令下发[id:{}] >>>>> {}", slave.getId(), array);
        //堆垛机任务写入后,回读一次,看是否成功
@@ -375,7 +377,6 @@
            }
        }
        try {
            // 日志记录
            BasCrnOptService bean = SpringUtils.getBean(BasCrnOptService.class);
@@ -402,7 +403,7 @@
        if (result != null && result.IsSuccess) {
            Thread.sleep(200);
            this.readStatus();
//            News.info("堆垛机命令下发[id:{}] >>>>> {}", slave.getId(), JSON.toJSON(command));
            News.info("堆垛机命令下发[id:{}] >>>>> {}", slave.getId(), JSON.toJSON(command));
            OutputQueue.CRN.offer(MessageFormat.format("【{0}】[id:{1}] >>>>> 命令下发: {2}", DateUtils.convert(new Date()), slave.getId(), JSON.toJSON(command)));
            return true;
        } else {
src/main/java/com/zy/service/impl/MainServiceImpl.java
@@ -50,7 +50,6 @@
 */
@Slf4j
@Service("mainService")
@Transactional
public class MainServiceImpl {
    @Autowired
@@ -106,6 +105,7 @@
     * 组托
     * 入库站,根据条码扫描生成入库工作档,工作状态 2
     */
    @Transactional(rollbackFor = Exception.class)
    public synchronized void generateStoreWrkFile() {
        String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
        // 根据输送线plc遍历
@@ -249,6 +249,7 @@
    /**
     * 拣料、并板、盘点再入库
     */
    @Transactional(rollbackFor = Exception.class)
    public synchronized void stnToCrnStnPick(Integer mark) {
        for (DevpSlave devp : slaveProperties.getDevp()) {
            // 遍历拣料入库口
@@ -443,20 +444,42 @@
    /**
     * 入出库  ===>>  堆垛机入出库作业下发
     * 注意:使用 REQUIRES_NEW 让每个堆垛机的处理在独立事务中执行,避免长时间持有锁导致死锁
     */
    public synchronized void crnIoExecute(Integer mark) {
        try {
        for (CrnSlave crn : slaveProperties.getCrn()) {
                try {
                    // 每个堆垛机的处理在独立事务中执行,快速提交释放锁
                    processCrnIo(crn, mark);
                } catch (Exception e) {
                    News.error(""+mark+" - crnIoExecute"+" - 处理堆垛机{}时发生异常", crn.getId(), e);
                    // 继续处理下一个堆垛机,不中断整个流程
                }
            }
        } catch (Exception e) {
            News.error(""+mark+" - crnIoExecute"+" - 执行堆垛机入出库作业下发时发生异常", e);
            }
    }
    /**
     * 处理单个堆垛机的入出库作业(使用独立事务,快速提交释放锁)
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    public void processCrnIo(CrnSlave crn, Integer mark) {
            // 获取堆垛机信息
            CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, crn.getId());
        if (crnThread == null) {
            return;
        }
            CrnProtocol crnProtocol = crnThread.getCrnProtocol();
            if (crnProtocol == null) {
                continue;
            return;
            }
            BasCrnp basCrnp = basCrnpService.selectById(crn.getId());
            if (basCrnp == null) {
                News.error(""+mark+" - 1"+" - {}号堆垛机尚未在数据库进行维护!", crn.getId());
                continue;
            return;
            }
            // 只有当堆垛机空闲 并且 无任务时才继续执行
@@ -489,8 +512,6 @@
            // 库位移转
            //mark - 3 - ....
            this.locToLoc(crn, crnProtocol,mark);
        }
    }
    /**
@@ -577,15 +598,22 @@
                } else if (shallowLoc.getLocSts().equals("F") || shallowLoc.getLocSts().equals("D")) {
                    News.warnNoLog(""+mark+" - 1"+" - 12"+" - // F、D  库位状态={}",shallowLoc.getLocSts());
                    // 检查是否已存在移库任务
                    WrkMast waitWrkMast = wrkMastMapper.selectByLocNo1(shallowLocNo);
                    // 此标记避免多次执行移库任务
                    if (Cools.isEmpty(wrkMast.getUpdMk()) || "N".equals(wrkMast.getUpdMk())) {
                    if (Cools.isEmpty(waitWrkMast) && (Cools.isEmpty(wrkMast.getUpdMk()) || "N".equals(wrkMast.getUpdMk()))) {
                        wrkMast.setUpdMk("Y");
                        wrkMast.setIoPri(14D);
                        wrkMastMapper.updateById(wrkMast);
                        // 生成工作档,将浅库位移转到新的库位中
                        try {
                        moveLocForDeepLoc(slave, shallowLoc,mark);
                        // 生成工作档、改变浅库位的源库/目标库 库位状态、下发堆垛机命令(立马执行)
//                        moveLocForDeepLocPakin(slave, shallowLoc, wrkMast);
                            News.warnNoLog("{}任务已生成浅库位移转任务,浅库位号:{},继续处理下一个任务", wrkMast.getWrkNo(), shallowLocNo);
                        } catch (Exception e) {
                            News.error("{}任务生成浅库位移转任务失败,浅库位号:{}", wrkMast.getWrkNo(), shallowLocNo, e);
                        }
                    } else if (!Cools.isEmpty(waitWrkMast)) {
                        News.warnNoLog("{}任务入库等待中,浅库位已有移库任务,浅库位号:{},移库任务号:{}", wrkMast.getWrkNo(), shallowLocNo, waitWrkMast.getWrkNo());
                    }
                    continue;
                } else if (shallowLoc.getLocSts().equals("Q")) {
@@ -738,10 +766,19 @@
                                wrkMast.setUpdMk("Y");
                                wrkMastMapper.updateById(wrkMast);
                                // 生成工作档,将浅库位移转到新的库位中
                                try {
                                moveLocForDeepLoc(slave, shallowLoc,mark);
                                    News.warnNoLog("{}任务已生成浅库位移转任务,浅库位号:{},继续处理下一个任务", wrkMast.getWrkNo(), shallowLocNo);
                                    continue; // 已生成移库任务,继续处理下一个任务
                                } catch (Exception e) {
                                    News.error("{}任务生成浅库位移转任务失败,浅库位号:{}", wrkMast.getWrkNo(), shallowLocNo, e);
                                    continue; // 生成失败,继续处理下一个任务
                            }
                            News.error("{}任务出库失败,浅库位堵塞!浅库位号:{}", wrkMast.getWrkNo(), shallowLocNo);
                            break;
                            } else {
                                // 已存在移库任务,等待移库完成
                                News.warnNoLog("{}任务出库等待中,浅库位已有移库任务,浅库位号:{},移库任务号:{}", wrkMast.getWrkNo(), shallowLocNo, waitWrkMast.getWrkNo());
                                continue; // 继续处理下一个任务,不阻塞当前循环
                            }
                        } else if (shallowLoc.getLocSts().equals("Q") || shallowLoc.getLocSts().equals("S")) {
                            News.warnNoLog(""+mark+" - 2"+" - 10"+" - // Q、S  库位状态={}",shallowLoc.getLocSts());
                            WrkMast waitWrkMast = wrkMastMapper.selectByLocNo1(shallowLocNo);
@@ -1041,6 +1078,7 @@
    /**
     * 空栈板初始化入库,叉车入库站放货
     */
    @Transactional(rollbackFor = Exception.class)
    public synchronized void storeEmptyPlt(Integer mark) {
        for (DevpSlave devp : slaveProperties.getDevp()) {
@@ -1322,6 +1360,7 @@
    /**
     * 出库  ===>> 工作档信息写入led显示器
     */
    @Transactional(rollbackFor = Exception.class)
    public synchronized void ledExecute() {
        for (LedSlave led : slaveProperties.getLed()) {
            // 获取输送线plc线程