Skip to content

Instantly share code, notes, and snippets.

@sarmbruster
Last active August 25, 2016 15:56
Show Gist options
  • Save sarmbruster/4feb9bb446ae580cf71deb83810f071b to your computer and use it in GitHub Desktop.
Save sarmbruster/4feb9bb446ae580cf71deb83810f071b to your computer and use it in GitHub Desktop.
sample code for simulating merging two nodes and a relationship in between in a concurrent safe way
private void mergeConnectedNodes(Label myLabel, RelationshipType relationshipType, String propertyKey, String valueA, String valueB) {
try (Transaction tx = db.beginTx()) {
// get or create start end node
Node a = mergeAndLockNode(myLabel, propertyKey, valueA);
Node b = mergeAndLockNode(myLabel, propertyKey, valueB);
grabLocksInConsistentOrder(tx, a,b);
boolean aIsCheaper = a.getDegree(relationshipType) < b.getDegree(relationshipType);
Node cheaperNode = aIsCheaper ? a : b;
Node otherNode = aIsCheaper ? b : a;
if (!hasRelationshipBetween(cheaperNode, otherNode, relationshipType)) {
cheaperNode.createRelationshipTo(otherNode, relationshipType);
}
tx.success();
}
}
private boolean hasRelationshipBetween(Node cheaperNode, Node otherNode, RelationshipType relationshipType) {
boolean result = false;
for (Relationship r : cheaperNode.getRelationships(relationshipType)) { // consider direction here if reltype is directional in real life
if (r.getOtherNode(cheaperNode).equals(otherNode)) {
return true;
}
}
return result;
}
private Node mergeAndLockNode(Label myLabel, String propertyKey, Object propertyValue) {
Node node = db.findNode(myLabel, propertyKey, propertyValue);
if (node == null) {
node = db.createNode(myLabel);
node.setProperty(propertyKey, propertyValue);
}
return node;
}
private void grabLocksInConsistentOrder(Transaction tx, Node... nodes) {
SortedMap<Long, Node> orderedNodesById = new TreeMap<>();
for (Node node : nodes) {
orderedNodesById.put(node.getId(), node);
}
for (Node node: orderedNodesById.values()) {
tx.acquireWriteLock(node);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment