对大型数据集进行操作时,Spring Data会提供两个抽象:Stream
和Page
。我们已经使用Stream
一段时间了,没有任何问题,但是最近我想尝试一种分页的方法并遇到可靠性问题。
请考虑以下内容:
@Entity
public class MyData {
}
public interface MyDataRepository extends JpaRepository<MyData, UUID> {
}
@Component
public class MyDataService {
private MyDataRepository repository;
// Bridge between a Reactive service and a transactional / non-reactive database call
@Transactional
public void getAllMyData(final FluxSink<MyData> sink) {
final Pageable firstPage = PageRequest.of(0, 500);
Page<MyData> page = repository.findAll(firstPage);
while (page != null && page.hasContent()) {
page.getContent().forEach(sink::next);
if (page.hasNext()) {
page = repository.findAll(page.nextPageable());
}
else {
page = null;
}
}
sink.complete();
}
}
使用两个Postgres 9.5数据库,源数据库具有接近100,000行,而目标数据库为空。然后使用示例代码将其从源复制到目标。最后,我发现目标数据库的行数比源数据库小得多。
事实证明,我最终多次处理相同的行(结果是丢失了其他行)。这使我发现了其他人已经遇到的修补程序,您应该在其中提供一个Sort.by("")
参数。
更改服务以使用后:
// Make our pages sorted by the PKEY
final Pageable firstPage = PageRequest.of(0, 500, Sort.by("id"));
我发现虽然它极大地帮助了我,但我仍然会处理多行(从丢失大约一半的行到只看到约12个重复项)。当我改用Stream
时,我没有问题。
有人对发生的事情有任何解释吗?在测试运行至少10到15分钟之前,我似乎没有任何重复,这几乎使我相信在客户端或客户端上发生了某种会话或其他超时数据库)导致打ic。但是我真的不在我的知识范围内,无法对其进行进一步的故障排除了。