Neo4j Java org.neo4j.graphdb.NotInTransactionException 报错分析

tech2025-01-19  5

在 Java代码中创建 Neo4j 新节点 Node 或者新 Relationship 的时候,需要在 Transaction 里面进行,然而当创建完毕,使用 tx.commit() 关掉当前的 Transaction 之后,在 Transaction 中的 Node 对象也就失效了。所以如果想在 Transaction 之外使用某个节点属性的值,需要在 Transaction 有效的时候获取并储存需要的属性值。如果先创建节点,之后还需要用到该节点,最好储存该点的id信息,使用一个 Transaction 来创建,再使用另一个 Transaction 来获取这个节点并进行之后的操作。

错误示范:

Node n; try(Transaction tx = graphDB.beginTx(){ n = tx.createNode(label); n.setProperty(PROPERTY,value); tx.commit(); } System.out.println(n.getProperty(PROPERTY));//这时候因为Transaction已经关闭,这个节点n的reference失效了,所以无法读取该点的信息

如果运行这段代码,会报以下的错:

Exception in thread "main" org.neo4j.graphdb.NotInTransactionException: The transaction has been closed. at org.neo4j.kernel.impl.coreapi.TransactionImpl.checkInTransaction(TransactionImpl.java:695) at org.neo4j.kernel.impl.coreapi.TransactionImpl.kernelTransaction(TransactionImpl.java:576) at org.neo4j.kernel.impl.core.NodeEntity.getProperty(NodeEntity.java:428)

正确例子:

Node n; try(Transaction tx = graphDB.beginTx(){ n = tx.createNode(label); n.setProperty(PROPERTY,value); System.out.println(n.getProperty(PROPERTY)); //或者进行其他对这个新节点的操作 tx.commit(); } Label mynomeLabel = Label.label("mynome"); // Node node; // BAD! Don't do! try (Transaction tx = graphDatabase.beginTx()) { Node node = tx.createNode(mynomeLabel); node.setProperty("Id", "xxxx"); tx.commit(); } try (Transaction tx = graphDatabase.beginTx()) { Node node = graphDatabase.findNode(mynomeLabel, "Id", "xxxx" ); // TODO tx.commit(); }

参考: [1] https://stackoverflow.com/questions/63715290/transaction-close-commit-issue-in-neo4j-java [2] https://community.neo4j.com/t/notintransactionexception-in-neo4j-4-0-3-embedded/17559/2

最新回复(0)