public Relationship createRelationship( Node startNodeProxy, NodeImpl startNode, Node endNode, RelationshipType type) { if (startNode == null || endNode == null || type == null) { throw new IllegalArgumentException( "Null parameter, startNode=" + startNode + ", endNode=" + endNode + ", type=" + type); } if (!relTypeHolder.isValidRelationshipType(type)) { relTypeHolder.addValidRelationshipType(type.name(), true); } long startNodeId = startNode.getId(); long endNodeId = endNode.getId(); NodeImpl secondNode = getLightNode(endNodeId); if (secondNode == null) { setRollbackOnly(); throw new NotFoundException("Second node[" + endNode.getId() + "] deleted"); } long id = idGenerator.nextId(Relationship.class); int typeId = getRelationshipTypeIdFor(type); RelationshipImpl rel = newRelationshipImpl(id, startNodeId, endNodeId, type, typeId, true); RelationshipProxy proxy = new RelationshipProxy(id, relationshipLookups); TransactionState transactionState = getTransactionState(); transactionState.acquireWriteLock(proxy); boolean success = false; TransactionState tx = transactionState; try { transactionState.acquireWriteLock(startNodeProxy); transactionState.acquireWriteLock(endNode); persistenceManager.relationshipCreate(id, typeId, startNodeId, endNodeId); if (startNodeId == endNodeId) { tx.getOrCreateCowRelationshipAddMap(startNode, typeId).add(id, DirectionWrapper.BOTH); } else { tx.getOrCreateCowRelationshipAddMap(startNode, typeId).add(id, DirectionWrapper.OUTGOING); tx.getOrCreateCowRelationshipAddMap(secondNode, typeId).add(id, DirectionWrapper.INCOMING); } // relCache.put( rel.getId(), rel ); relCache.put(rel); success = true; return proxy; } finally { if (!success) { setRollbackOnly(); } } }
public Relationship createRelationship(Node startNode, Node endNode, RelationshipType type) { if (startNode == null || endNode == null || type == null) { throw new IllegalArgumentException( "Null parameter, startNode=" + startNode + ", endNode=" + endNode + ", type=" + type); } if (!relTypeHolder.isValidRelationshipType(type)) { relTypeHolder.addValidRelationshipType(type.name(), true); } int startNodeId = (int) startNode.getId(); NodeImpl firstNode = getLightNode(startNodeId); if (firstNode == null) { setRollbackOnly(); throw new NotFoundException("First node[" + startNode.getId() + "] deleted"); } int endNodeId = (int) endNode.getId(); NodeImpl secondNode = getLightNode(endNodeId); if (secondNode == null) { setRollbackOnly(); throw new NotFoundException("Second node[" + endNode.getId() + "] deleted"); } int id = idGenerator.nextId(Relationship.class); RelationshipImpl rel = new RelationshipImpl(id, startNodeId, endNodeId, type, true, this); boolean firstNodeTaken = false; boolean secondNodeTaken = false; acquireLock(rel, LockType.WRITE); boolean success = false; try { acquireLock(firstNode, LockType.WRITE); firstNodeTaken = true; acquireLock(secondNode, LockType.WRITE); secondNodeTaken = true; int typeId = getRelationshipTypeIdFor(type); persistenceManager.relationshipCreate(id, typeId, startNodeId, endNodeId); firstNode.addRelationship(type, id); secondNode.addRelationship(type, id); relCache.put((int) rel.getId(), rel); success = true; return new RelationshipProxy(id, this); } finally { boolean releaseFailed = false; if (firstNodeTaken) { try { releaseLock(firstNode, LockType.WRITE); } catch (Exception e) { releaseFailed = true; e.printStackTrace(); log.severe("Failed to release lock"); } } if (secondNodeTaken) { try { releaseLock(secondNode, LockType.WRITE); } catch (Exception e) { releaseFailed = true; e.printStackTrace(); log.severe("Failed to release lock"); } } releaseLock(rel, LockType.WRITE); if (!success) { setRollbackOnly(); } if (releaseFailed) { throw new LockException( "Unable to release locks [" + startNode + "," + endNode + "] in relationship create->" + rel); } } }