SDA中的Threadsafe域模型getOrCreate?

时间:2012-10-17 11:13:40

标签: thread-safety neo4j spring-data-neo4j

使用SDN 2.1.0.BUILD-SNAPSHOT

是否存在执行getOrCreate的域级线程安全方式?

我有

@NodeEntity
public class ResourceEntity  extends Entity {

@Fetch
@Indexed(unique=true)
String url;

@Fetch
String platform;
}

我想要的是能够访问neo4j REST数据库,并添加一个新的ResourceEntity,或者检索已经存在的那个,如果已经有一个具有指定的url字段...

我找不到的是一种原子性的方式。它需要以原子方式工作,因为会有多个线程调用此代码。

neo4jTemplate.save(resourceEntity);
如果我尝试插入带有重复键的ResourceEntity,那么

抛出(应该)org.springframework.dao.DataIntegrityViolationException,但是在域级别的Neo4jTemplate上暴露的 是getOrCreate,这就是我想要的。如何在SDN中实现这一点,而不必像

那样做一些不整洁的事情
Map<String, Object> properties = new HashMap<String, Object>();
properties.put("url", url);
properties.put("__type__", "com.mydomain.analysis.thingie.dao.ResourceEntity");

Node node = neo4jTemplate.getOrCreateNode("ResourceEntity", "url", "url", properties);

...然后从存储库或类似的东西拉回新的ResourceEntity ......讨厌!(我没有测试过,但我认为这样可行) - 但它非常难看!

1 个答案:

答案 0 :(得分:0)

您有没有找到问题的答案?我们面临着类似的问题,实际上已经实现了您提出的解决方法:getOrCreate函数,它尝试使用存储库findByPropertyValue函数从图中检索节点/边。如果未找到节点/边缘,则创建新节点/边缘。

此解决方法的问题是,使用例如单独的JSON调用调用getOrCreate函数,导致执行不同的getOrCreate事务。如果这些不同的事务在节点/边缘方面重叠,则在事务同时运行时会创建重复的节点/边缘。

处理这种副作用的一种方法是为节点/边唯一ID使用唯一索引: @Indexed(unique = true)

虽然这似乎是一个更大的解决方法。

Neo4j / Spring / SDG人员的任何想法/最佳实践?