在 try-with-resources 块之外流式传输 JOOQ 结果时,我是不是会冒 JDBC 连接泄漏的风险?
Posted
技术标签:
【中文标题】在 try-with-resources 块之外流式传输 JOOQ 结果时,我是不是会冒 JDBC 连接泄漏的风险?【英文标题】:Do I risk a JDBC connection leak when streaming JOOQ results outside a try-with-resources block?在 try-with-resources 块之外流式传输 JOOQ 结果时,我是否会冒 JDBC 连接泄漏的风险? 【发布时间】:2016-06-04 03:47:44 【问题描述】:我有一个 JOOQ 查询,我想避免同时实现所有记录。 (但是,我可以将所有从它们创建的 bean 对象联合具体化。)
我有以下简单的方法来加载数据:
public List<CustomerInfo> getCustomers()
return dslContext
.selectFrom(CUSTOMER)
// <-- note the missing .fetch()
.stream()
.map(CustomerInfo::new)
.collect(Collectors.toList());
这会在任何情况下导致 JDBC 连接泄漏吗? (例如CustomerInfo::new
中的异常)
【问题讨论】:
【参考方案1】:我已经尝试过找到一种方法来注册一个可靠的流“完成”钩子,该钩子会在完整的流消耗或任何异常时触发,但不幸的是,这是不可能的:Register a Stream "completion" hook
所以,确实,您显示的代码不正确。操作“惰性”流(或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:
这本质上与 fetchLazy() 相同,但不是返回 Cursor,而是返回 Java 8 Stream。客户端应确保正确关闭 Stream,例如在 try-with-resources 语句中
【讨论】:
以上是关于在 try-with-resources 块之外流式传输 JOOQ 结果时,我是不是会冒 JDBC 连接泄漏的风险?的主要内容,如果未能解决你的问题,请参考以下文章
java9新特性-增强的try-with-resources块
你是否还在写try-catch-finally?来使用try-with-resources优雅地关闭
由编译器完成的 Java try-with-resource 实现