簡體   English   中英

Neo4j-在使用Java創建關系時無法回滾事務

[英]Neo4j - Unable to rollback transaction in creating relationships with java

我正在嘗試通過Maven Java應用程序在Neo4j中創建一些節點,並在這些節點之間創建關系。 我確實想創建16807個節點和17210368個關系。 我讀取了一個文件,並獲得了row變量,該row變量具有必須創建的節點數,並且還具有一個包含34420736元素的list (= 17210368 * 2)。 我想創建一個從node [列表的元素0]到node [列表的元素1],從node [列表的元素2]到node [列表的元素3]等的關系。列表的最大元素也是16807。我創建一個ArrayList<Node>來動態創建節點,因為我希望程序以不同的文件(和不同的行值)運行。

這是我的代碼:

    GraphDatabaseFactory dbFactory = new GraphDatabaseFactory();
    GraphDatabaseService graphDb = dbFactory.newEmbeddedDatabase("C:\Users\....\default.graphdb");

    Transaction tx = graphDb.beginTx();
    try {
        final RelationshipType type2 = DynamicRelationshipType.withName("KNOW");

        ArrayList<Node> nodelist = new ArrayList<Node>();

        for (int k = 0; k < row; k++) { //row=16807
            nodelist.add(graphDb.createNode());
            nodelist.get(k).setProperty("Name", "ListNode  " + k);
        }       

        int count=0;
        for (int j = 0; j < list.size() ; j++) { //list.size()=34420736
            nodelist.get(list.get(count)).createRelationshipTo(nodelist.get(list.get(count+1)), type2);
            count=count+2;
        }

        tx.success();
    }
    finally {
        tx.close();
    }
    graphDb.shutdown();

如果我在不嘗試創建關系的情況下運行代碼,則它將創建節點並正確運行。 當我添加用於創建realtionships的for循環時,將引發以下錯誤:

Exception in thread "main" org.neo4j.graphdb.TransactionFailureException: Unable to rollback transaction
at org.neo4j.kernel.TopLevelTransaction.close(TopLevelTransaction.java:131)
at com.mycompany.traverse_test.traverse_main.main(traverse_main.java:138)
Caused by: java.lang.IllegalStateException: No RelationshipState for added relationship!
at org.neo4j.kernel.api.txstate.RelationshipChangeVisitorAdapter$1.visit(RelationshipChangeVisitorAdapter.java:132)
at org.neo4j.kernel.api.txstate.RelationshipChangeVisitorAdapter.visitAddedRelationship(RelationshipChangeVisitorAdapter.java:83)
at org.neo4j.kernel.api.txstate.RelationshipChangeVisitorAdapter.visitAdded(RelationshipChangeVisitorAdapter.java:106)
at org.neo4j.kernel.api.txstate.RelationshipChangeVisitorAdapter.visitAdded(RelationshipChangeVisitorAdapter.java:47)
at org.neo4j.kernel.impl.util.diffsets.DiffSets.accept(DiffSets.java:76)
at org.neo4j.kernel.impl.api.state.TxState.accept(TxState.java:156)
at org.neo4j.kernel.impl.api.KernelTransactionImplementation.rollback(KernelTransactionImplementation.java:542)
at org.neo4j.kernel.impl.api.KernelTransactionImplementation.close(KernelTransactionImplementation.java:404)
at org.neo4j.kernel.TopLevelTransaction.close(TopLevelTransaction.java:112)
... 1 more

有任何想法嗎??

由於代碼中的錯誤,Neo4j試圖回滾事務。 它無法回滾的事實可能是neo4j中的錯誤,但這實際上不是您的主要問題。

查看您的代碼,看來您遍歷了list太多次了。 也就是說, list循環中的代碼一次使用了2個列表元素,因此您只應循環list.size()/2次。

這是應該修復該錯誤的代碼,並且還進行了其他一些改進。

GraphDatabaseFactory dbFactory = new GraphDatabaseFactory();
GraphDatabaseService graphDb = dbFactory.newEmbeddedDatabase("C:\Users\....\default.graphdb");

Transaction tx = graphDb.beginTx();
try {
    final RelationshipType type2 = DynamicRelationshipType.withName("KNOW");

    ArrayList<Node> nodelist = new ArrayList<Node>();

    for (int k = 0; k < row; k++) { //row=16807
        Node node = graphDb.createNode();
        node.setProperty("Name", "ListNode  " + k);
        nodelist.add(node);
    }       

    for (int j = 0; j < list.size() ; j += 2) { //list.size()=34420736
        nodelist.get(list.get(j)).createRelationshipTo(
            nodelist.get(list.get(j+1)), type2);
    }

    tx.success();
} catch(Throwable e) {
    e.printStackTrace();
    // You may want to re-throw the exception, rather than just eating it here...
} finally {
    tx.close();
}
graphDb.shutdown();

[編輯]

但是,由於上面的代碼試圖在單個事務中創建這么多的資源(16K節點和17M關系),因此它們仍然會耗盡內存。

以下示例代碼在多個事務中完成工作(一個用於創建節點和節點列表,多個用於關系)。

NUM_RELS_PER_CHUNK指定每個事務中要創建的最大關系數。 必須修改createRelEndpointList()方法以填充關系端點(節點)索引的列表(每個索引是nodeList節點的0起始位置)。

public class MyCode {

    private static final int NODE_COUNT = 16807;
    private static final int NUM_RELS_PER_CHUNK = 1000000;

    public static void main(String[] args) {
        doIt();
    }

    private static void doIt() {
        GraphDatabaseFactory dbFactory = new GraphDatabaseFactory();
        GraphDatabaseService graphDb = dbFactory.newEmbeddedDatabase(new File("C:\\Users\\....\\default.graphdb"));

        try {
            RelationshipType type = DynamicRelationshipType.withName("KNOW");

            List<Node> nodeList = createNodes(graphDb, NODE_COUNT);
            List<Integer> list = createRelEndpointList();

            final int numRels = list.size() / 2;
            final int numChunks = (numRels + NUM_RELS_PER_CHUNK - 1)/NUM_RELS_PER_CHUNK;

            int startRelIndex = 0, endRelIndexPlus1;
            for (int i = numChunks; --i >= 0 && startRelIndex < numRels; ) {
                endRelIndexPlus1 = (i > 0) ? startRelIndex + NUM_RELS_PER_CHUNK : numRels;
                createRelationships(graphDb, nodeList, list, startRelIndex, endRelIndexPlus1, type);
                startRelIndex = endRelIndexPlus1;
            }
        } finally {
            graphDb.shutdown();
        }
    }

    private static List<Node> createNodes(GraphDatabaseService graphDb, int rowCount) {
        ArrayList<Node> nodeList = new ArrayList<Node>(rowCount);
        Transaction tx = graphDb.beginTx();
        try {
            final StringBuilder sb = new StringBuilder("ListNode  ");
            final int initLength = sb.length();
            for (int k = 0; k < rowCount; k++) {
                Node node = graphDb.createNode();
                sb.setLength(initLength);
                sb.append(k);
                node.setProperty("Name", sb.toString());
                nodeList.add(node);
            }
            tx.success();
            System.out.println("Created nodes.");
        } catch(Exception e) {
            e.printStackTrace();
            tx.failure();
            return null;
        } finally {
            tx.close();
        }
        return nodeList;
    }

    private static List<Integer> createRelEndpointList() {
        final List<Integer> list = new ArrayList<Integer>();

        // Fill
        //   list
        //     ...

        return list;
    }

    private static void createRelationships(GraphDatabaseService graphDb, List<Node> nodeList, List<Integer> list, int startRelIndex, int endRelIndexPlus1, RelationshipType type) {
        Transaction tx = graphDb.beginTx();
        try {
            final int endPlus2 = endRelIndexPlus1 * 2;
            for (int j = startRelIndex * 2; j < endPlus2; ) {
                Node from = nodeList.get(list.get(j++));
                Node to =   nodeList.get(list.get(j++));
                from.createRelationshipTo(to, type);
            }
            tx.success();
            System.out.println("Created rels. Start: " + startRelIndex + ", count: " + (endRelIndexPlus1 - startRelIndex));
        } catch(Exception e) {
            e.printStackTrace();
            tx.failure();
            // You may want to re-throw the exception, rather than just eating it here...
        } finally {
            tx.close();
        }
    }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM