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 @   意犹未尽  阅读(21)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
历史上的今天:
2020-07-16 redis-缓存设计-记录前一个小时和最新的日志
2020-07-16 redis-运维-性能测试
2020-07-16 redis-使用-pipeline大批量提交提高性能
2020-07-16 redis-使用-事物
点击右上角即可分享
微信分享提示