我正在尝试为批量查询爬虫操作创建抽象。想法是执行查询,获得结果集,并且对于每一行执行提交或回滚的操作。要求是处理所有行,不管是否存在故障,并且结果集未事先加载到内存中。
问题可归结为这样一个事实:在回滚后无法维护打开的结果集。这是根据规范,游标可保持性在提交时可以维护(使用ResultSet.HOLD_CURSORS_OVER_COMMIT),但不能在回滚时维护。
使用JTA / JDBC语义的简单实现,提供两个扩展点,一个用于指定查询,另一个用于指定每行的实际操作,如下所示:
UserTransaction tx = getUserTransaction();
tx.begin();
ResultSet rs = executeQuery(); //extension point
tx.commit();
while(rs.next()) {
tx.begin();
try {
performOperationOnCurrentRow(ResultSet rs); //extension point
tx.commit();
logSuccess();
}catch(Exception e) {
tx.rollback();
logFailure(e);
}
}
这似乎不是一个牵强附会的场景,但我在网上发现的相关信息很少。问题是,任何流行的框架都能优雅地解决这个问题吗?我不一定需要一个开箱即用的解决方案,我只是想知道是否有一个已知的良好/普遍接受的方法来处理这种情况。
一种解决方案是跟踪失败的行并在该点之后重新打开游标,这通常需要强制执行一些扩展规则(例如,有序的结果集,使用where子句上的最后一个失败的行id进行查询等) )。
另一种方法是使用两个不同的线程进行查询和行操作。
你会做什么?
答案 0 :(得分:1)
由于这几年没有回答,我会继续自己回答。
我们制定的解决方案围绕着这个过程(称为BatchProcess
)执行Query
(不限于SQL,请注意)并将其结果添加到并发{{1}的想法。 }。 Queue
生成许多BatchProcess
个对象(在新线程上运行),这些对象使用QueueProcessor
的条目并执行使用该条目作为输入的Queue
。每个Operation
执行都作为一个单独的工作单元执行。底层事务管理器是JTA实现。
有点过时,但在某些时候,实施是https://bo2.googlecode.com/svn/trunk/Bo2ImplOpen/main/gr/interamerican/bo2/impl/open/runtime/concurrent/BatchProcess.java
在该回购中的某个地方甚至还有一个用于BatchProcess监控和管理的GUI;)
免责声明:这个人有很多关于此设计和实施的事项https://stackoverflow.com/users/2362356/nakosspy