Inconsistent transaction beheviour w/remote:
Version: 3.0.27
Java-gremlin api
Connection mode: remote
Goal
- 3 threads deleting 3 different nodes.
Context
- Each threads has its own
GraphTraversalSourcegenerated as
OrientGraph g = ogFactory.getTx();
g.makeActive()
GraphTraversalSource gts = g.traversal()
- Code (simplified)
Transaction t;
for (int retry=5; retry>=0; retry--) {
try {
gts.tx().open();
gts.V(object_id).drop().iterate();
gts.tx().commit()
break;
} catch (OConcurrentModificationException ocm) {
gts.tx().rollback();
} catch (Exception e) {
// ...
}
}
What happens
- one thread completes
- the other 2 raise
OConcurrentModificationException - one of the remaining completes
- the other raises
ORecordNotFoundException
What should happen
Once the last thread tries to commit, either it succeed or it should fail with an OConcurrentModificationException.
The ORecordNotFoundException suggests that the rollback operation had not any effect, and instead the node was previously removed even tough we had an OConcurrentModificationException.
P.S.
Using plocal: the correct sequence of Exceptions is raised
Hi @MartinBrugnara
do you have a complete test to reproduce this case?
Thanks
Hi @wolf4ood, the code i posted is part of a much bigger framework which I cannot share at the moment. Nevertheless, I extracted for you all the relevant code: https://pastebin.com/9E45Z7G0 . Then you will need just a main function, imports, and the following deps:
<dependencies>
<dependency>
<groupId>org.apache.tinkerpop</groupId>
<artifactId>gremlin-core</artifactId>
<version>3.4.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.orientechnologies/orientdb-gremlin -->
<dependency>
<groupId>com.orientechnologies</groupId>
<artifactId>orientdb-gremlin</artifactId>
<version>3.0.27</version>
</dependency>
<dependency>
<groupId>com.orientechnologies</groupId>
<artifactId>orientdb-client</artifactId>
<version>3.0.27</version>
</dependency>
</dependencies>
Cheers, M
EDIT: GdbLogger is just a custom logger... feel free to replace it with prints, and the invocations to fatal() with System.exit(1).