我有一个大文件要在数据库表中导入。 文件中的每一行代表DB中的一行。 我的要求是将文件行拆分为批次并将每个批次保存在DB上(在事务中)。如果事务失败,我想终止导入,避免导入后续批次。
从this tutorial开始,我建立了这条路线:
from("file:/path")
.split(body().tokenize("\n"))
.streaming()
.bean(ParseLine.class)
.setHeader("foo", constant("foo"))
.aggregate(header("foo"), new ArrayListAggregationStrategy())
.completionSize(100)
.completionTimeout(1000)
.bean(SaveBatch.class)
.end();
其中ParseLine
bean返回一个准备好进行数据库插入的对象,SaveBatch
bean是执行插入的代码片段
而ArrayListAggregationStrategy
是:
class ArrayListAggregationStrategy implements AggregationStrategy {
public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
Object newBody = newExchange.getIn().getBody();
ArrayList<Object> list = null;
if (oldExchange == null) {
list = new ArrayList<Object>();
list.add(newBody);
newExchange.getIn().setBody(list);
return newExchange;
} else {
list = oldExchange.getIn().getBody(ArrayList.class);
list.add(newBody);
return oldExchange;
}
}
}
这里的问题是,如果SaveBatch bean抛出异常,此路由不会停止文件处理,但bean将继续接收所有后续聚合。 在SaveBean抛出的第一个异常上是否存在对拆分器的策略? 提前致谢
答案 0 :(得分:2)
尝试将.stopOnException()
添加到您的拆分器,如Splitter (stopOnException)所示。
from("file:/path")
.split(body().tokenize("\n")).stopOnException()
.streaming()
.bean(ParseLine.class)
.setHeader("foo", constant("foo"))
.aggregate(header("foo"), new ArrayListAggregationStrategy())
.completionSize(100)
.completionTimeout(1000)
.bean(SaveBatch.class)
.end();
答案 1 :(得分:1)
你可以在分裂上指定两个东西,添加一个参数stopOnException = true 然后,您可以为路径或路径的特定部分指定onexception,并将标记处理为true。一旦发生异常,路由将停止拆分,并且当抛出异常时,您的整体路由例外策略将根据需要处理它。
<camelContext xmlns="http://camel.apache.org/schema/spring">>
<camel:onException>
<camel:exception>java.lang.Exception</camel:exception>
<camel:handled>
<camel:constant>true</camel:constant>
</camel:handled>
<camel:to uri="log:sundarstop?showAll=true&multiline=true" />
<camel:stop></camel:stop>
</camel:onException>
<camel:route>
<camel:from uri="file://///"/>
<camel:to .../>
</camel:route>
</camelContext>
答案 2 :(得分:0)
在camel中定义异常处理程序并开始从ArrayListAggregationStrategy
类中抛出相应的异常。