Reputation: 1666
Is there a way to manually acquire write lock on a certain set of nodes via Neo4J Java API or Cypher?
There are examples in documentation, but only for embedded Neo4j version. Standard Java Transaction
interface does not contain such methods: https://neo4j.com/docs/api/java-driver/current/org/neo4j/driver/v1/Transaction.html
Also I can't find a way to do it via Cypher.
Upvotes: 3
Views: 399
Reputation: 2749
To extend the answer of @InverseFalcon, here is an example for the write lock by writing to a node:
@Test
public void testPessimisticLocking() throws InterruptedException {
txn.execute(status -> {
session.query("CREATE (n:Lock {uuid:'test'})", Map.of(), false);
return null;
});
ExecutorService executor = Executors.newFixedThreadPool(2);
Runnable task = () -> {
LOG.debug("Starting task");
txn.execute(status -> {
long time = System.nanoTime();
LOG.debug("Locking node with time={}", time);
session.query("MATCH (n:Lock {uuid:'test'}) SET n.time = {0}", Map.of("0", time), false);
LOG.debug("Query done, waiting some time...");
try {
Thread.sleep(5000);
}
catch (InterruptedException e) {
LOG.warn("Interrupted", e);
}
LOG.debug("Waiting done");
return null;
});
LOG.debug("Finished task");
};
for (int i = 0; i < 2; i++) {
executor.execute(task);
}
executor.shutdown();
executor.awaitTermination(20, TimeUnit.MINUTES);
}
The test creates a node of label "Lock". It starts two tasks in parallel that try to acquire the write lock on the node. Each task is waiting 5sec within the transaction once it has acquired the lock (simulates workload). Debug output is:
2019-10-26 09:47:09,502 [pool-3-thread-1] DEBUG - Starting task
2019-10-26 09:47:09,508 [pool-3-thread-1] DEBUG - Locking node with time=82297334790500
2019-10-26 09:47:09,513 [pool-3-thread-2] DEBUG - Starting task
2019-10-26 09:47:09,515 [pool-3-thread-2] DEBUG - Locking node with time=82297342219000
2019-10-26 09:47:09,605 [pool-3-thread-2] DEBUG - Query done, waiting some time...
2019-10-26 09:47:14,627 [pool-3-thread-2] DEBUG - Waiting done
2019-10-26 09:47:14,643 [pool-3-thread-1] DEBUG - Query done, waiting some time...
2019-10-26 09:47:14,645 [pool-3-thread-2] DEBUG - Finished task
2019-10-26 09:47:19,643 [pool-3-thread-1] DEBUG - Waiting done
2019-10-26 09:47:19,841 [pool-3-thread-1] DEBUG - Finished task
In the log you can see that one task is acquiring the lock just when the other task finished the transaction.
Upvotes: 1
Reputation: 30397
You can take a write lock by writing to a node, such as by setting or removing a property. I think this also works when removing non-existent properties.
If you have APOC Procedures installed, you can call the apoc.lock.nodes()
procedure, passing it a list of the nodes to lock.
Upvotes: 3