我在MySQL DB的查询中使用流式传输。工作正常,直到我在流媒体中发出另一个查询。这完全可以,并在java.sql.SQLException中解释:
Streaming result set com.mysql.jdbc.RowDataDynamic@16559dec is still active. No statements may be issued when any streaming result sets are open and in use on a given connection. Ensure that you have called .close() on any active streaming result sets before attempting more queries.
因为我真的想在流媒体中间进行第二次查询,显然我只需要使用另一个数据库连接。
那么如何强制在同一个线程中使用另一个连接呢?
我正在使用Spring Data with Hibernate
请不要建议一次提取或分页,这不是问题的关键。
编辑:
计划流程:
答案 0 :(得分:1)
所以1个线程{ 1. open conn, 2 - 8. asyncroneously stream, 9. close conn }, { 3. open or use conn, 4. query, 9. close or skip }
??
如果流式传输足够短,请尝试使用连接池。
否则,这也是大流更好地作为文件名存储在数据库中的情况(例如使用UUID生成文件名)。然后流式传输可以在数据库之外完成,你可以节流流式传输来阻碍自制的DenialOfService。
问题被重新编辑后。
所以场景是:
void f() {
open conn
do a java 8 stream
g()
close conn
}
void g() {
open conn
...
close conn
}
这是可能的,有几种处理方式:使用单个全局连接,使用连接池,事务性或不是cq。自动提交。
对于查询,我猜最重要的是关闭事物。试用资源是不泄漏资源的理想选择。
try (Connection conn = ...) {
...
try (PreparedStatement stm = conn.prepareStatement(sql)) {
...
try (ResultSet rs = stm.executeQuery()) {
... the stream
}
}
}
上面也关闭了ResultSet,这可能让你陷入困境。
您也可以通过流传递它,它可以访问结果集。
由于Stream也是AutoCloseable,您可能需要在那里调整代码。或者使用CachedRowSet
而不是ResultSet。
很抱歉这个不确定的答案。
答案 1 :(得分:0)
我不确定我完全理解你想做什么。我认为你想要流式传输数据,以某种方式转换每个项目,然后坚持结果。如果是这种情况,我相信使用带有注释@Transactional(propagation = Propagation.REQUIRES_NEW)
的单独“持久”方法应该可以解决问题。
如果你想要多个处理你的流(比如说,因为你做了一些REST调用,或者由于其他原因你认为可能需要很长时间),你可能要考虑将流元素推送到一个阻塞队列,有多个线程从那里读取,并为每个项目做你需要做的任何事情。