java陷阱之遍历数据源数据

日常我们执行刷数更新避免使用分页偏移,如何涉及到条件变更会丢数据

比如满足条件的数据 1 2  3 4  5 6 7

根据分页偏移查询当处理第一页1 2,1 2处理后不满足条件分页指针偏移到2,这个时候条件1 2已经不满足了 就丢了3 4数据

采用id偏移的方式

针对要修改的db场景,还应该避免大事务

 

    @Override
    @Transactional(timeout = 10, propagation = Propagation.NEVER, rollbackFor = Exception.class)
    public ReturnT<String> execute(String paramStr) throws Exception {
        log.info("#22 TempAlarmOrderOrgCodeRefreshTask  任务执行计划调度 开始执行刷数,paramStr:{},开始时间:{}",
            paramStr, DateHelper.format(new Date(), DateHelper.DATETIME_FORMAT));
        LambdaQueryWrapper<PO> wrapper = Wrappers.lambdaQuery();

        // 设置查询条件:erp_org_code 为 NULL 或者为空字符串
        wrapper.and(w -> w.isNull(PO::getErpOrgCode)
            .or().eq(PO::getErpOrgCode, ""));

        // 设置排序条件:按 id 升序排序
        wrapper.orderByAsc(PO::getId);
        Page<ColdChainAlarmOrder> page = new Page<>();
        int currentPage = 1;
        int pageSize = 100;
        Long lastId = 0L;
        Long updatedTotalCount = 0L;
        Integer index = 0;
        //是否到最后一页
        boolean isLastPage = false;
        while (true) {
            //最后一页结束
            if (isLastPage) {
                break;
            }
            index++;
            page.setCurrent(currentPage);
            page.setSize(pageSize);
            //每次读取第一页,id指针偏移
            wrapper.gt(PO::getId, lastId);
            IPage<?> pageResult = mapper.selectPage(page, wrapper);
            //未查到数据 表示没有需要处理数据
            if (CollectionUtils.isEmpty(pageResult.getRecords())) {
                break;
            }
            //查询数量小于分页数量表示最后一页
            isLastPage = pageResult.getRecords().size() < pageSize;
            //获取最后一个升序的id 用于指针偏移
            lastId = pageResult.getRecords().get(pageResult.getRecords().size() - 1).getId();
            List<PO> records = pageResult.getRecords();
            List<String> storeCodes = records.stream().map(PO::getStoreCode)
                .filter(storeCode -> StringUtils.isNotBlank(storeCode)).collect(Collectors.toList());
            //需要根据门店获取,如果没有数据则忽略
            if (CollectionUtils.isEmpty(storeCodes)) {
                continue;
            }
            //走代理开启事务一批一批修改
            Integer updatedCount = applicationContext.getBean(this.getClass())
                .batchUpdateErpCode(执行修改的po);
        }
    }
    @Transactional(timeout = 10, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Integer batchUpdateErpCode(List<PO> updateErpCodOrders) {
        
    }

 

posted @ 2024-07-16 16:25  意犹未尽  阅读(40)  评论(0)    收藏  举报