1

我是图形数据库的新手,我在让 api 在事务中工作时遇到了问题。

我有一个简单的代码,它使用 neo4j graph db api 创建节点和关系。我的代码在 JUnit 中运行,并尝试使用下面给出的开始和结束事务创建 2 个节点以及它们之间的关系。

该代码在快乐的情况下工作正常。但是,如果代码中出现问题,节点仍会提交到图形数据库中。不知道我在这里做错了什么。我本来希望创建的 2 个节点被回滚。

这是代码片段:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:/applicationContext.xml" })
public class RestBatchLoaderTest {  

    @Autowired
    SpringRestGraphDatabase graphDatabaseService;

@Test
public void createNode() {
    Transaction tx =graphDatabaseService.beginTx();

    try {
        Map<String,Object> nodeprops1 = new HashMap<String, Object>();
        nodeprops1.put("name", "James Parker");
        nodeprops1.put("age", Integer.valueOf(11));
        Node james = graphDatabaseService.createNode(nodeprops1);           
        Assert.assertNotNull(james);

        Map<String,Object> nodeprops2 = new HashMap<String, Object>();
        nodeprops2.put("name", "Bing P");
        nodeprops2.put("age", Integer.valueOf(34));
        Node bing= graphDatabaseService.createNode(nodeprops2);

        Node aa = null;
                    // Failure point: should rollback the previous node in the finally.
        graphDatabaseService.remove(aa);            


        Map<String,Object> relprops = new HashMap<String, Object>();
        RelationshipType type = new RelationshipType() {

            @Override
            public String name() {
                return "MARRIED_TO";
            }
        };
        graphDatabaseService.createRelationship(joe, jane, type, relprops);
        tx.success();

    } finally {
        tx.finish();
    }
}

graphDatabaseService对象是使用 spring 配置自动装配的。这是配置:

<neo4j:config graphDatabaseService="graphDatabaseService"/>
<bean id="graphDatabaseService" class="org.springframework.data.neo4j.rest.SpringRestGraphDatabase">
    <constructor-arg value="http://localhost:7474/db/data/"/>
</bean>

另外,我注意到在上面的代码中调用graphDatabaseService.beginTx()时, tx对象是NullTransaction的一个实例。

任何想法,出了什么问题?

谢谢。

4

2 回答 2

1

我想知道问题出在哪里了。配置需要启用批处理 - 是的。我还使用了图形数据库对象的 RestAPI 包装器将其作为一个原子代码运行。请参见下面的代码:

@Autowired
SpringRestGraphDatabase graphDatabaseService;

private RestAPI restAPI;

@Before
public void init(){
    this.restAPI = ((RestGraphDatabase)graphDatabaseService).getRestAPI();
}

@Test
public void testEnableBatchTransactions() throws Exception {
    System.setProperty(Config.CONFIG_BATCH_TRANSACTION,"true");
    Transaction tx = restAPI.beginTx();
    try {
        Node n1 = restAPI.createNode(map("name", "node1"));
        Node n2 = restAPI.createNode(map("name", "node2"));
        Node n3 = restAPI.createNode(map("name", "node3"));
        //String s = null;
        //s.toString();
        Node n4 = restAPI.createNode(map("name", "node4"));      
        tx.success();
    } finally {
         tx.finish();
    }


    assertTrue(tx instanceof BatchTransaction);
} 

System.setProperty(Config.CONFIG_BATCH_TRANSACTION,"true");启用批处理模式。

要对此进行测试,请尝试取消注释代码片段并运行测试。节点n1n2n3不会在数据库中提交。

于 2013-06-26T22:12:25.773 回答
0

您按原样指定graphDatabaseService.remove(aa);为故障aaNULL。查看文档,org.springframework.data.neo4j.rest.SpringRestGraphDatabase如果Exception节点是NULL. 您是否验证过实际上引发了异常?否则你的代码将运行到tx.success();. 如果抛出异常,请进一步说明您使用的是什么版本的 neo4j 和 spring。


编辑:

在阅读了更多内容之后,我在源代码中org.springframework.data.neo4j.rest.SpringRestGraphDatabase看到它应该给你一个NullTransaction基本上什么都不做的(见这里)。此外,Spring Data neo4j documentation每个操作都在自己的事务中,因为 neo4j REST 适配器不允许跨多个操作的事务(请参阅此处)。

于 2013-06-26T00:17:52.883 回答