2012-10-19 32 views
2

我正在尝试为批量查询爬虫操作创建抽象。其思想是执行查询,获得结果集,并为每一行执行提交或回滚操作。要求是所有的行都被处理,而不管是否有失败,并且结果集没有事先加载到内存中。批量查询爬虫操作模式

问题归结为在回滚之后无法维护打开的结果集这一事实。根据规范,游标可保存性在提交时保持不变(使用ResultSet.HOLD_CURSORS_OVER_COMMIT),但不在回滚时保持不变。

一个天真的实现与JTA/JDBC语义,提供两个扩展点,一个用于指定specifing实际操作的每一行的查询和一个,会是这样的:

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进行查询等等)。

另一种情况是将两个不同的线程用于查询和行操作。

你会怎么做?

回答

1

由于这个问题现在还没有得到解答,所以我会继续自己回答。

我们制定的解决方案围绕着这个过程(称为BatchProcess)执行Query(不限于SQL,介意您)并将其结果添加到并发Queue的想法。 BatchProcess会产生若干使用Queue条目的QueueProcessor对象(在新线程上运行),并执行使用该条目作为输入的Operation。每个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

UML diagrams for Batch Process objects