Neo4j Transactions直到整个过程运行完毕,数据才持久存在

时间:2019-09-13 15:24:54

标签: neo4j

我有一个过程,该过程针对Hive执行多个SQL语句,然后每个语句以周期性的提交样式遍历结果,并为每个10.000个结果打开一个事务。对于较小的量,过程将运行,但仅在处理所有语句时保留数据。在不限制数据的情况下,即使对于具有〜4.000.000结果的一条语句,该过程也会在〜1.500.000结果之后陷入困境,即使这些结果应该已经保留,也没有。

对于每个结果,检查是否已经存在对应的节点,如果不存在,则创建该节点并设置属性。因此,没有任何幻想。

我尝试通过Neo4j REST API而不是浏览器启动该过程,该浏览器适用于运行在3.3上的生产服务器,但适用于运行在3.5.9上的新测试服务器,即使这样做没有帮助,并且过程卡住了。 我还尝试了不同的负载,只是在一个测试过程中创建了数百万个节点(没有配置单元只是虚拟节点),这相当快,但是直到过程执行完之后,仍然没有保留更改。

由于apoc现在支持蜂巢,因此我使用apoc.load.jdbc和apoc.periodic.iterate将更简单的节点类型转换为CYPHER,这完全符合预期。但是由于时间限制,我无法将每种情况都转换为CYPHER。除了直接使用JAVA API外,还应该比cypher快。

所有神奇的事情都发生在以下方法中:

/**
 * @param statement the prepared sql statement to be executed against hive
 * @param label current node type 
 * @param filterId the indexed property on the given nodetype
 * @return the custom node counter object that keeps track of the number of created and processed nodes
 * @throws SQLException 
 */
public NodeCounter writeDataInGraphDB(PreparedStatement statement, Label label, String filterId, GraphDatabaseService db, Log log) throws SQLException {
    NodeCounter nc = new NodeCounter();
    int commitSize = 10000;

    ResultSet rs = statement.executeQuery();
    while (rs.next()) {
        int currentTransaction = 0;
        boolean b = true;
        try (Transaction tx = db.beginTx()) {
            while (currentTransaction < commitSize && b) {
                if (currentTransaction > 0) b = rs.next();
                currentTransaction++;
                nc.totalNodes++;

                Node n = db.findNode(label, filterId, rs.getLong(filterId));
                // Check if node exists
                if (n == null) {
                    // Create new node
                    nc.newNodes++;
                    n = db.createNode(label);
                    setProperties(rs, n);
                }
            }
            tx.success();
            log.info("Transaction closed: New " + nc.newNodes + " Changed " + nc.changedNodes + " Total " + nc.totalNodes);
        } catch (SQLException e) {
            log.error(classname + methodname + "An error has occured", e);
        }
    }
    rs.close();

    log.info("Datasets: " + nc.totalNodes + " - New Nodes: " + nc.newNodes + " - Changed Nodes: " + nc.changedNodes);
    return nc;
}

卡住的程序以越来越大的世界暂停消息的形式出现

Detected VM stop-the-world pause: {pauseTime=16115, gcTime=157, gcCount=1}

什么也没有发生,只会暂停更多的世界。

我希望使用事务能够持久化定期创建的节点,因为根据文档,一旦将事务标记为成功并关闭,事务就将其更改持久化(在我的情况下是通过自动关闭进行的) )。但是它们只保留一次(如果过程执行完)。

通过浏览器或REST API进行的调用周围是否存在某种隐藏的主事务,该事务仅在计算完所有内容后才保留更改?如此之多的结果要一口气保留下来,以至于Neo无法应对?

0 个答案:

没有答案