【发布时间】:2018-07-17 06:10:20
【问题描述】:
根据http://orientdb.com/docs/3.0.x/java/Java-Query-API.html的流式示例,我们可以使用Orient结果集流式API如下
ODatabaseDocument db;
...
String statement = "SELECT FROM V WHERE name = ? and surnanme = ?";
OResultSet rs = db.query(statement, "John", "Smith");
rs.stream().forEach(x -> System.out.println(x.getProperty("age")));
rs.close();
这很好但是太琐碎了——如果我们需要保留 rs/stream 怎么办?我们不能很好地关闭结果集,因为我们希望在 Web 应用程序中的后续用户请求中重用流,例如(在分页等场景中)。
但是为了让流“活着”,Orient 用户指南说:
OResultSet 被实现为一个分页结构,它包含一些 迭代器在迭代期间打开。这在远程和 在嵌入式使用中。
您应该始终在结束时调用 OResultSet.close() 执行,以释放资源。
OResultSet 实例在您关闭时自动关闭 返回它们的 ODatabase。
始终关闭结果集很重要,即使它们是 转换为流(在流被消耗后)。
在这方面是否有任何最佳做法。据我所知,我们需要:
1) 保持东方数据库连接打开,直到用户“分页”会话完成(可以说是 5-10 分钟)。只有当用户说“完成”时,我们才能关闭结果集并关闭数据库连接。因此,Orient 数据库连接(以及它生成的任何流)对单个应用程序用户来说是“私有的”。此外,由于每个用户请求都可以在不同的线程上激活,因此在使用它之前,需要在当前线程上激活所述数据库连接。
2) 使用 Java Stream API 浏览“任意”大型结果集的任意子集。底层 Orient db 流实现如何处理内存使用情况?是什么决定了使用“单个 rs/流”并保持一段时间的内存使用情况?当我们有数千个开放的 rs/streams 时会发生什么,特别是如果每个用户都有自己正在查看的“私有”rs/streams?
3) 如果给定的 Orient 数据库连接一次只能在单个线程上使用(Orient 要求),我们如何处理具有自己自定义长寿命 rs/streams/connections 的多个用户?这是否意味着如果我们有 1000 个客户端使用他们自己的私有 rs/stream(他们坚持说 5 分钟),那么我们必须保持 1000 个数据库连接打开(即每个用户/rs 一个?)围绕这个的限制?这种风格显然与更典型的执行查询/关闭 rs 模式完全不同,用于快速用户交互,从一个请求到下一个请求是无状态的(对于给定范围每次重新执行查询的幼稚分页,这可能会变得昂贵)
附:我意识到,一旦我们获得了 Java 流,那么我们几乎就开始使用 Java API 本身——所以我想一旦你开始进入 Stream 接口,JOOQ 流的使用(例如)将与 Orient 流的使用非常相似——我不熟悉 Java Streams API,但我想How to paginate a list of objects in Java 8? 是一个不错的起点?
【问题讨论】: