Gremlin实现:确保book顶点仅存在一条owns入边的方法
确保Book顶点仅被单个Person拥有的Gremlin实现方案
方案一:添加边时直接校验入边状态
直接在Gremlin查询里嵌入判断逻辑,仅当目标book没有已存在的owns入边时,才执行添加操作:
g.V(book_1_id) .where(__.inE('owns').count().is(0)) .addE('owns') .from(V(person_1_id))
逻辑很直白:先定位到目标book顶点,检查它的owns入边数量为0(也就是还没被任何人拥有),满足条件才会创建从person到book的关联边。如果book已有拥有者,查询会返回空结果,不会产生任何新边。
方案二:用事务避免并发竞态问题
如果你的图数据库支持事务(比如JanusGraph、Neo4j等),可以把校验和添加操作放进同一个事务里,防止多请求同时操作时出现“同时通过校验导致重复绑定”的情况:
tx = g.tx().open() try { // 事务内查询无入边的目标book def targetBook = tx.V(book_1_id).where(__.inE('owns').count().is(0)).next() // 添加关联边 tx.addE('owns').from(tx.V(person_1_id)).to(targetBook).iterate() // 提交事务 tx.commit() } catch (NoSuchElementException e) { // 找不到符合条件的book,说明已有拥有者,回滚事务 tx.rollback() }
这种方式能保证操作的原子性:要么全部成功(book未被拥有时完成绑定),要么全部回滚(book已被拥有时不做任何修改)。
方案三:利用数据库原生约束(如果支持)
部分图数据库支持直接配置唯一性约束,从底层强制保证一个book只能被一个person拥有。比如Neo4j可以用Cypher语句添加约束:
CREATE CONSTRAINT ON (b:Book) ASSERT exists((:Person)-[:owns]->(b)) IS UNIQUE
注意:不是所有Gremlin兼容的数据库都支持这类原生约束,具体需参考你使用的数据库官方文档。
内容的提问来源于stack exchange,提问作者coderz
相关产品推荐
相关产品推荐

