简单的分页查询,竟然显示了重复的数据?

1,768 阅读2分钟

背景

今天突然很多用户反馈,小程序的订单列表,显示了重复的订单数据。吓得我们以为有什么新功能,导致订单显示出现了bug。经过排查发现是普通分页的引起的问题

场景还原

还原的路径也很简单。假设我们现在在查看订单列表 这时,突然有一个客户在前台付款了,此时我们查看下一页数据 你会发现,第一页的数据在第二页出现了。这个问题在pc端其实不明显,但是如果是在app或者小程序这种增量加载的场景,就会十分明显。所以还是需要去处理。

解决方案

首先为什么会出现这个问题,想必大家也能猜到。普通的分页是通过数据的偏移量去获取数据的。如果在分页查询的时候,我们的数据集不固定,例如数据新增或者删除。就会导致看到的数据重复或者缺失。 所以我们一般可以通过两个方向去考虑,一个是保证数据集固定,一个是保证数据不重复。

数据集固定

其实就是前端的解决方案。一般的查询都是会有时间范围,所以前端可以控制查询的结束时间最大不能超过用户进入订单页面的时间。 例如我们查询今天的订单,前端开始时间为当前的零点,而结束时间原本应该是当天的23:59:59,就改为用户进入订单列表页面时间如12:00:10。每次分页查询都是12:00:10作为结束时间,直到用户重新刷新页面,或者改动时间。 通过将结束时间进行固定,保证分页查询的数据集固定。但这个方案的前提时用户不能对数据进行删除。否则还是会出现数据缺失的情况。

保证数据不重复

后端的解决方案。也就是通过游标进行分页,在查询的时候新增一个有规律的字段进行添加过滤例如主键等。

SELECT * FROM order
WHERE id < cursorId
ORDER BY id DESC

但是作为游标的数据一定要唯一。 例如我们用时间作为游标进行过滤,当有相同时间的订单时,也会导致数据缺失的问题。

总结

普通分页由于数据集可能会变动,会导致分页查询的时候,出现数据重复或缺失的问题。可以通过前端固定时间保证数据集固定,或者后端通过游标过滤数据,保证数据不重复。根据业务场景不同,可以选择不同的方案进行处理。