当在 try-with-resources 块之外流式传输 JOOQ 结果时,我是否冒 JDBC 连接泄漏的风险?

Do I risk a JDBC connection leak when streaming JOOQ results outside a try-with-resources block?

我有一个 JOOQ 查询,我想避免同时具体化所有记录。 (但是,我可以共同实现所有从它们创建的 bean 对象。)

我有以下简单的加载数据的方法:

public List<CustomerInfo> getCustomers() {
    return dslContext
                .selectFrom(CUSTOMER)
                // <-- note the missing .fetch()
                .stream()
                .map(CustomerInfo::new)
                .collect(Collectors.toList());
}

这在任何情况下都会导致 JDBC 连接泄漏吗? (例如 CustomerInfo::new 中的异常)

我试过运气找到一种方法来注册一个可靠的流 "completion" 挂钩,该挂钩在完整的流消耗或任何异常时触发,但不幸的是,这是不可能的:

因此,确实,您显示的代码不正确。使用 "lazy" 流(或 Cursor)进行操作的正确方法是使用 try-with-resources 语句。下面两个是等价的:

// Using a Stream
try (Stream<CustomerRecord> stream = dslContext.selectFrom(CUSTOMER).stream()) {
    return stream.map(CustomerInfo::new).collect(Collectors.toList());
}

// Using a Cursor
try (Cursor<CustomerRecord> cursor = dslContext.selectFrom(CUSTOMER).fetchLazy()) {
    return cursor.stream().map(CustomerInfo::new).collect(Collectors.toList());
}

另请注意 ResultQuery.stream() javadoc:

This is essentially the same as fetchLazy() but instead of returning a Cursor, a Java 8 Stream is returned. Clients should ensure the Stream is properly closed, e.g. in a try-with-resources statement