【问题标题】:Neo4j procedure "The requested operation cannot be performed, because it has to be performed in a transaction..."Neo4j 程序“请求的操作无法执行,因为它必须在事务中执行......”
【发布时间】:2018-10-25 15:36:47
【问题描述】:

我正在为 Neo4j 3.3.5 编写以下程序:

/**
 * This procedure provides best sell products from a category
 *
 * @param category the category node for which we are searching for best sell items
 * @param limit    limit of returned products count
 */
@Procedure(value = "bestSell.category")
@Description("Get best sell items from a specified category")
public Stream<OutputResult> bestSellForCategory(
        @Name("category") Node category,
        @Name(value = "limit", defaultValue = "20") Long limit) {
    RelationshipType inCategoryType = RelationshipType.withName(IN_CATEGORY_RELATION);
    RelationshipType recentlyOrderedType = RelationshipType.withName(RECENTLY_ORDERED_RELATION);

    try {
        List<Node> productsInCateogory = new ArrayList<>();
        List<ScoredResult> scoredProducts = new ArrayList<>();

        for (Relationship relationship : category.getRelationships(inCategoryType, Direction.INCOMING)) {
            Node product = relationship.getOtherNode(category);
            productsInCateogory.add(product);
        }

        productsInCateogory.parallelStream().forEach(node -> {
            long i = 0;
            for (Relationship ignored : node.getRelationships(recentlyOrderedType, Direction.INCOMING)) {
                i++;
            }
            if (i != 0) {
                scoredProducts.add(new ScoredResult((Long) node.getProperty(DOC_ID_PROPERTY), i));
            }
        });
        return scoredProducts.stream().sorted((scoredResult, t1) -> (int) (scoredResult.score - t1.score)).limit(limit).map(s -> new OutputResult(s.docId));
    } catch (Exception e) {
        e.printStackTrace();
        throw new RuntimeException(e.getMessage());
    }
}

这是我为该程序编写的测试:

@Test
public void checkBestSellOutput() throws Throwable {
    try (Driver driver = GraphDatabase.driver(neo4j.boltURI(), Config.build().withoutEncryption().toConfig())) {
        Session session = driver.session();

        try (Transaction tx = session.beginTransaction()) {
            tx.run(
                    "MERGE (c:Category {categoryId:93})" +
                            "MERGE (p1:Product {docId:1})" +
                            "MERGE (p2:Product {docId:2})" +
                            "MERGE (p3:Product {docId:3})" +
                            "MERGE (p1)-[:IN_CATEGORY]->(c)" +
                            "MERGE (p2)-[:IN_CATEGORY]->(c)" +
                            "MERGE (p3)-[:IN_CATEGORY]->(c)" +
                            "MERGE (cust1:Customer {customerId:1})" +
                            "MERGE (cust2:Customer {customerId:2})" +
                            "MERGE (cust1)-[:RECENTLY_ORDERED]->(p1)" +
                            "MERGE (cust2)-[:RECENTLY_ORDERED]->(p1)" +
                            "MERGE (cust1)-[:RECENTLY_ORDERED]->(p2)");
            tx.success();
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }

        List<Record> results = session.run("MATCH (c:Category {categoryId: 93}) CALL bestSell.category(c, 20) YIELD docId RETURN docId").list();

        assertThat(results.size(), equalTo(2));
    }
}

当我尝试使用 maven 运行构建时,我收到以下错误: 无法调用过程bestSell.category:原因:java.lang.RuntimeException:无法执行请求的操作,因为它必须在事务中执行。确保您将操作包装在适当的事务样板中,然后重试。

我尝试了很多,但没有在文档中找到答案。我该如何解决?

【问题讨论】:

    标签: database graph neo4j transactions graph-databases


    【解决方案1】:

    请参阅Transaction JavaDoc 以获得简单的样板:

     try ( Transaction tx = graphDb.beginTx() )
     {
         // operations on the graph
         // ...
    
         tx.success();
     }
    

    以下是如何在程序中使用样板的示例。 @Context 注释将导致db 变量在运行时被注入适当的GraphDatabaseService 实例。

    import org.neo4j.graphdb.GraphDatabaseService;
    import org.neo4j.procedure.Context;
    .
    .
    .
    
    @Context
    public GraphDatabaseService db;
    
    /**
     * This procedure provides best sell products from a category
     *
     * @param category the category node for which we are searching for best sell items
     * @param limit    limit of returned products count
     */
    @Procedure(value = "bestSell.category")
    @Description("Get best sell items from a specified category")
    public Stream<OutputResult> bestSellForCategory(
            @Name("category") Node category,
            @Name(value = "limit", defaultValue = "20") Long limit) {
        RelationshipType inCategoryType = RelationshipType.withName(IN_CATEGORY_RELATION);
        RelationshipType recentlyOrderedType = RelationshipType.withName(RECENTLY_ORDERED_RELATION);
    
        try {
            List<Node> productsInCategory = new ArrayList<>();
            List<ScoredResult> scoredProducts = new ArrayList<>();
    
            try (Transaction tx = db.beginTx()) {
                for (Relationship relationship : category.getRelationships(inCategoryType, Direction.INCOMING)) {
                    Node product = relationship.getOtherNode(category);
                    productsInCategory.add(product);
                }
                productsInCategory.parallelStream().forEach(node -> {
                    long i = 0;
                    for (Relationship ignored : node.getRelationships(recentlyOrderedType, Direction.INCOMING)) {
                        i++;
                    }
                    if (i != 0) {
                        scoredProducts.add(new ScoredResult((Long) node.getProperty(DOC_ID_PROPERTY), i));
                    }
                });
                tx.success();
            }
    
            return scoredProducts.stream().sorted((scoredResult, t1) -> (int) (scoredResult.score - t1.score)).limit(limit).map(s -> new OutputResult(s.docId));
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-09-17
      • 2011-06-25
      • 1970-01-01
      • 2021-01-28
      • 1970-01-01
      • 2014-07-23
      • 1970-01-01
      相关资源
      最近更新 更多