Camel JDBC StreamList 查询似乎在拆分之前加载了整个结果集
Posted
技术标签:
【中文标题】Camel JDBC StreamList 查询似乎在拆分之前加载了整个结果集【英文标题】:Camel JDBC StreamList query appears to load whole resultset before splitting 【发布时间】:2019-05-13 09:39:36 【问题描述】:我正在运行一个 SQL 使用者来读取表中的更改,这一切都很好。但是,在某些情况下,批量发生更改,然后我的查询因内存不足错误而中断,正如您所料。
不幸的是,我被困在 Camel 2.17.6 上,因此 SQL 组件的 StreamList 选项不可用。 (尽管根据Camel-SQL Why using StreamList seems to load all ResultSet?,由于 Spring JDBC 限制,这不能作为流列表工作。)
所以我使用支持流列表的 JDBC 组件重新编写了我的路由,但只要我增加要提取的记录数,我仍然会出现内存不足异常。似乎出于某种原因,JDBC 组件试图在传递给拆分器之前提取所有记录。
我现在的形式是:
from("timer:timer...")
.to( "language:constant:resource:classpath:pathToSqlStatement/sqlStatement.sql" )
.to( "jdbc:msSqlServerDataSource?outputType=StreamList" )
.split( body() ).streaming()
.setBody().simple("$body[XMLDOC]")
.setHeader("HeaderName").xpath("xpath/to/data")
.to("jms:topic:name");
我最初确实有一个聚合策略 UseLatestAggregationStrategy
和 split()
之后的一个额外步骤,但我已经删除了它,试图删除可能导致整个查询被保存在内存中的所有内容,但我看不到我现在还能做什么。
我注意到问题camel jdbc out of memory exception 提出了类似的问题,但似乎没有解决方案。
(我应该注意我遇到的内存不足错误确实出现在不同的地方,包括GC overhead limit exceeded
WinNTFileSystem
,我不明白,还有其他与ZippedInputStream有关的事情,这又是我不明白。)
这是否意味着 StreamList 在 JDBC 组件上也不起作用,还是我必须做一些特定的事情来确保 JDBC 组件不会尝试缓存整个结果?
【问题讨论】:
【参考方案1】:我在使用 postgres 时遇到了类似的问题。将事务放在 jdbc 查询前面解决了我的问题。
问题的原因是,对于 postgres,自动提交标志必须为 false 才能获得流式传输结果,在骆驼路线中这样做的唯一方法似乎是在调用之前进行处理。
【讨论】:
【参考方案2】:从 v.18.x 版本开始,camel-sql 支持StreamList
输出类型。在早期版本中,camel-sql 组件加载result set in memory as list。我认为在 camel-sql 版本 2.17.x 中无法避免。
通过camel-sql组件将结果加载到内存后,聚合/拆分确实适用。
Another related answer.
【讨论】:
嗨@skadya!谢谢 - 正如我在我的问题中所说,我意识到StreamList
不在 2.17.x 中,所以根据手册重铸使用从 2.14 支持 StreamList
的camel-jdbc 的路线。
有趣的是,我刚刚在更高版本中进行了测试,而 Camel JDBC 组件仍然没有流式传输查询。但是,2.20 SQL 组件确实可以像我期望的那样使用 StreamList!但是,现在我被困在 2.17 上,所以在我升级服务器之前没有多大帮助。以上是关于Camel JDBC StreamList 查询似乎在拆分之前加载了整个结果集的主要内容,如果未能解决你的问题,请参考以下文章
从 Camel 和 Spring Boot 到 MS SQL Server 的 JDBC