Neo4j 如何保证在事务中的两个现有节点之间只创建一个新的唯一节点
我的图中有以下两个现有节点 由唯一客户编号标识的客户节点。 由唯一ISBN标识符标识的产品节点 我想在一个客户节点和一个产品节点之间创建关联。 但我想将此关联表示为一个名为许可节点的新节点,该节点将有一个到客户节点的链接和一个到产品节点的链接 此许可证节点将生成一个新的内部标识符作为随机GUID 我的应用程序中创建新的许可证节点并将其链接到其他2个节点的逻辑在一个事务中执行Neo4j 如何保证在事务中的两个现有节点之间只创建一个新的唯一节点,neo4j,cypher,spring-data-neo4j,neo4j-ogm,Neo4j,Cypher,Spring Data Neo4j,Neo4j Ogm,我的图中有以下两个现有节点 由唯一客户编号标识的客户节点。 由唯一ISBN标识符标识的产品节点 我想在一个客户节点和一个产品节点之间创建关联。 但我想将此关联表示为一个名为许可节点的新节点,该节点将有一个到客户节点的链接和一个到产品节点的链接 此许可证节点将生成一个新的内部标识符作为随机GUID 我的应用程序中创建新的许可证节点并将其链接到其他2个节点的逻辑在一个事务中执行 if(尚未与该客户的许可证关联的产品) 使用新的随机GUID创建新的许可证节点 创建从新许可证节点到产品节点的关系 创建从
if(尚未与该客户的许可证关联的产品)
使用新的随机GUID创建新的许可证节点
创建从新许可证节点到产品节点的关系
创建从客户节点到新许可证节点的关系
但是,多个请求可以使用相同的ISBN和客户号同时到达。
发生这种情况时,我有时会收到为同一客户和产品节点创建的重复许可证节点。
SpringDataNeo4j中的事务似乎并没有阻止这种情况的发生
如何确保在客户节点和产品节点之间只创建一个许可证节点
SpringDataNeo4j中的事务似乎并没有阻止这种情况的发生
Neo4j已读取事务的提交隔离级别。要防止这种情况,您需要可序列化
要实现您的需求,您可以:
- 在执行
尚未与…关联的产品检查之前,锁定产品和客户节点。您可以使用类似这样的查询(在同一事务中)来执行此操作: 与客户类似
- 向许可证添加一个特殊密钥,它是产品ID和客户ID的串联-然后在该密钥上创建一个唯一的约束
MATCH(p:Product),其中ID(p)={ID}设置p._lock=1
,在事务结束时使用MATCH(p:Product),其中ID(p)={ID}删除p._lock
。事务开始时的REMOVE n._lock
也应该可以工作,并在事务结束时为您保存一个查询。是的,这也奏效了。我想我理解了,因为删除属性可以确保在节点上使用写锁在添加、更改或删除节点或关系上的属性时,将对特定节点或关系执行写锁定。
我注意到,在进一步测试后,我现在可以重新构建一个测试,其中仅通过一次调用删除属性是不起作用的。但是,在检查之前设置属性,然后在tx代码末尾删除属性,这对我的所有测试都有效(我永远无法100%测试)。我想知道,如果Neo4j检测到您试图删除一个不存在的属性,并且在早期版本中它可能已经这样做了,那么它是否可能没有在节点上使用写锁?@DonalHurley这是什么版本的Neoj4?你能分享一下这个测试用例吗?
MATCH (n:Product) WHERE ID(n) = {id} REMOVE n._lock