分页查询在某些场景下引发的数据漏处理问题

简介: 分页查询在某些场景下引发的数据漏处理问题

背景

问题描述

假设有一个表字段statues,我们分页获取数据。status初始状态为1,我们分批获取数据,每一批获取1000,对数据进行处理,如果处理成功就更新status为2,否则不更新。

注意事项:

分页循环查询满足条件的数据然后进行处理,通过PageHelper或者直接使用“limit statIndex,pageSize”来分页查看数据,如果查询条件(如根据status来过滤数据)在每一次获取之后会更改,这里的更改可能指的是在每次循环查询内部更改满足查询条件的数据,如status=1的条件,在查询完之后更改为status=2,注意这里的更改还有可能出现在另外的逻辑链条中。

又或者将status=1的记录删除,或者再增加新的status=1的记录,这些都是类似问题,都会导致分页的数量

原有代码

List<User> userList;
int startPage = NumberUtils.INTEGER_ONE;
int bachSize = 10;
do {
    PageHelper.startPage(startPage, bachSize);
    // 查询用户列表
    userList = userMapper.listNeedApproveUser(xxx);
    if (CollectionUtils.isNotEmpty(userList)) {
        for (User user : userList) {
            // 处理用户审核状态
            int updNum = userMapper.updateApproveStatus(yyy);
        }
    }
    startPage++;
} while (userList.size() == bachSize);

分页查询后的变更过程如下

我们看到,原本在第二页的数据跑到第一页去了,而我们找第二页数据时,6、7两条数据就被丢弃了。相信看图大家都应该看懂了,道理也很简单,但在做得时候却忽略了。

更新之后的代码

针对上面所说的分页查询方式,我们需要做一些调整,调整办法如下:

  • 第一步:当查询出当页的数据之后,记录下本次拉取的最后一条数据的排序字段值;当发起下一页数据查询的时候,带上这个参数,服务端通过这个参数做过滤条件
  • 第二步:排序字段值不能出现重复
List<User> userList;
int bachSize = 10;
Long idGreater = NumberUtils.LONG_ZERO;
do {
// 查询用户列表select * from user where approve_status = #{approveStatus} and id > ${idGreater} order by id asc limit ${pageSize}
userList = userMapper.listNeedApproveUser(xxx, idGreater, bachSize);
if (CollectionUtils.isEmpty(userList)) {
break;
}
// 将本次循环查询到的最大id作为下次执行的startIndex,id > #{startIndex}
idGreater = userList.get(userList.size() - 1).getId();
for (User user : userList) {
// 处理用户审核状态
int updNum = userMapper.updateApproveStatus(yyy);
}
} while (transferImeiDetailList.size() == MAX_BATCH_SIZE);

相关文章

https://zhuanlan.zhihu.com/p/617014259

本篇文章如有帮助到您,请给「翎野君」点个赞,感谢您的支持。


目录
相关文章
|
SQL Java 数据库
【MybatisPlus】MP的分页查询、多条件查询以及查询过程中解决null的空值判定
分页查询、多条件查询以及查询过程中解决null的空值判定
1386 0
【MybatisPlus】MP的分页查询、多条件查询以及查询过程中解决null的空值判定
|
2月前
|
SQL 存储 关系型数据库
深分页怎么导致索引失效了?提供6种优化的方案!
深分页怎么导致索引失效了?提供6种优化的方案!
|
2月前
|
Oracle 关系型数据库 数据库
分页查询相关知识:一篇文章让你豁然开朗
分页查询相关知识:一篇文章让你豁然开朗
25 0
|
9月前
|
Java 数据库 Spring
【异常解决】解决mybatis-plus分页查询默认最多查询500条记录的问题,真是个大坑啊
【异常解决】解决mybatis-plus分页查询默认最多查询500条记录的问题,真是个大坑啊
224 0
|
Java 数据库连接 mybatis
【手撕Mybatis的分页插件】【查询结果集是0,直接返回[]】【提高查询我们的性能】
【手撕Mybatis的分页插件】【查询结果集是0,直接返回[]】【提高查询我们的性能】
【手撕Mybatis的分页插件】【查询结果集是0,直接返回[]】【提高查询我们的性能】
|
小程序 API 数据库
小程序中的分页查询
小程序中的分页查询
小程序中的分页查询
|
Java 数据库连接 数据库
mybatis中查询时间段内的数据(当只有一个时间字段时)
mybatis中查询时间段内的数据(当只有一个时间字段时)
669 0
mybatis中查询时间段内的数据(当只有一个时间字段时)
|
SQL 关系型数据库 MySQL
mysql优化大批量数据时的分页操作
mysql大数据量下的优化分页的方式,仅供参考。
mysql优化大批量数据时的分页操作