我是图表数据库的新手,我遇到了在交易中获取api工作的问题。
我有一个简单的代码,它使用neo4j图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 的一个实例。
任何想法,出了什么问题?
感谢。
答案 0 :(得分:1)
我认为弄清楚问题是什么。配置需要启用批处理 - true。我还使用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");
启用批处理模式。
要对此进行测试,请尝试取消注释代码段并运行测试。节点 n1 , n2 和 n3 将不会在数据库中提交。
答案 1 :(得分:0)
您指定graphDatabaseService.remove(aa);
作为失败点,aa
为NULL
。查看org.springframework.data.neo4j.rest.SpringRestGraphDatabase
的文档,如果节点为Exception
,则不会记录NULL
。你确认实际抛出了异常吗?否则,您的代码将一直运行到tx.success();
。如果抛出异常,请进一步指定您正在使用的neo4j和spring版本。
修改强>
在阅读了一点之后,我在org.springframework.data.neo4j.rest.SpringRestGraphDatabase
的来源中看到它应该给你NullTransaction
基本上什么都不做(见here)。
此外,Spring Data neo4j documentation
表示每个操作都在其自己的事务中,因为neo4j REST适配器不允许跨多个操作的事务(请参阅here)。