orientdb: Cannot update the record because the version is not the latest
Hi,
This is probably a very old question, but slightly different in my case and haven’t found answer in group, so post it again.
Following is my code snippet.
- With blueprints
@Test
public void testTransaction() {
OrientGraph graph = new OrientGraph("remote:localhost/tmp", "admin", "admin");
Vertex a = null;
try {
a = graph.addVertex(null);
graph.stopTransaction(TransactionalGraph.Conclusion.SUCCESS);
} catch (Exception e) {
graph.stopTransaction(TransactionalGraph.Conclusion.FAILURE);
e.printStackTrace();
}
try {
for (int i = 0; i < 100; ++i) {
graph.addEdge(null, graph.addVertex(null), a, "");
}
graph.stopTransaction(TransactionalGraph.Conclusion.SUCCESS);
} catch (Exception e) {
graph.stopTransaction(TransactionalGraph.Conclusion.FAILURE);
e.printStackTrace();
}
try {
Vertex b = graph.addVertex(null);
graph.addEdge(null, b, a, "");
graph.stopTransaction(TransactionalGraph.Conclusion.SUCCESS);
} catch (Exception e) {
graph.stopTransaction(TransactionalGraph.Conclusion.FAILURE);
e.printStackTrace();
} finally {
graph.shutdown();
}
}
- Without blueprints
@Test
public void testTransactionNative() {
OGraphDatabase db = new OGraphDatabase("remote:localhost/tmp");
db.open("admin", "admin");
ODocument a = null;
try {
db.begin(OTransaction.TXTYPE.OPTIMISTIC);
a = db.createVertex().save();
db.commit();
} catch (Exception e) {
db.rollback();
e.printStackTrace();
}
try {
db.begin(OTransaction.TXTYPE.OPTIMISTIC);
for (int i = 0; i < 100; ++i) {
db.createEdge(db.createVertex().save(), a.save()).save();
}
db.commit();
} catch (Exception e) {
db.rollback();
e.printStackTrace();
}
try {
db.begin(OTransaction.TXTYPE.OPTIMISTIC);
db.createEdge(db.createVertex().save(), a.save()).save();
db.commit();
} catch (Exception e) {
db.rollback();
e.printStackTrace();
} finally {
db.close();
}
}
Both versions I will get exception when committing the third transaction like: om.orientechnologies.orient.core.exception.OConcurrentModificationException: Cannot UPDATE the record #7:4 because the version is not the latest. Probably you are updating an old record or it has been modified by another user (db=v2 your=v1)
The problem here is “a” actually, when I create the edge, if I try to “save” it again, then I will get the above exception; while if not, everything is fine.
But in blueprints, “a” will always be saved:
public Edge addEdge(final Object id, final Vertex outVertex, final Vertex inVertex, final String label) {
// ...
// SAVE THE VERTICES TO ASSURE THEY ARE IN TX
db.save(((OrientVertex) outVertex).getRawElement());
db.save(((OrientVertex) inVertex).getRawElement());
edge.save();
return edge;
}
I’ve tried to disable level1 and level2 cache, and disable mvcc, but nothing works.
How can I solve this problem? Or is it not expected to use a vertex/edge created in another transaction?
About this issue
- Original URL
- State: closed
- Created 11 years ago
- Comments: 47 (24 by maintainers)
Hi @maggiolo00 , I upgraded the version to 3.04, it works way better now. There are very infrequent instances, when i get the same error, but the gremlin requests are not freezing now.
I am having a similar error. I am using
orientDB-tp3-3.0.2and gremlin_python to connect to orientdb and run queries. I open a thread from the python application (only 1 thread), it runs all gremlin queries sequentially.Right now I am testing with 3 vertices and 2 edges creation. I successfully create the 3 vertices and am able to create the first edge. The second edge creation throws the error :
500: Cannot UPDATE the record #23:8 because the version is not the latest. Probably you are updating an old record or it has been modified by another user (db=v2 your=v1)I also get a similar error when I try to drop the graph. I use :
> g.E().drop().iterate()- works fine> g.V().drop().iterate()- throws error> g.V().drop().iterate()- works fine after a few tries and after trying some other queries in betweenAs far as I can tell, ODB offers serializable isolation and they want to switch to something more like snapshotting (possibly).
https://github.com/orientechnologies/orientdb/issues/6013
I have no idea how transaction contention priority should work and seems like it isn’t needed, with ODBs OCC system. There are no locks in ODB’s transaction system.
I also think the ODB docs on the transaction system is a bit misleading.
This sentence is correct:
So, this part of the code with the retries is basically incorrect.
There can be no retry, because every retry will fail. The data is stale. As the sentence above states “retire the transaction”, you’d have to go to the user and let them know their update failed, ask them to refresh the page and try again (in a web app) i.e. the conflict is resolved by the user.
So, if there are scenarios where retries will work and will get the transaction to commit, those scenarios aren’t clarified in the docs. From what I am reading, only stale data (version conflicts) would be the reason for transactions or non-transactional updates to fail, which means you must resolve the conflict and that means getting the fresh version, making the changes again and saving.
Scott
@smolinari Imagine you use orientdb with lots of clients and high-traffic. All clients starts transactions in any kind of size (orientdb recommend small transactions because of concurrency issues) what happens? You will run into lots of concurrency issues which you have to solve with a retry logic but the end is not in sight because you need a magical retry number??? I dont get the picture of that concept and I can’t imagine that all other database vendors goes with the same approach.
@saeedtabrizi @laa I think the problem is that orientdb use OCC instead MVCC or a MIX of both. There are MVCC in transactions but the strategy looks very chaotic because orientdb says:
I think I speak to lots of developers when I say thats some of a reason why I use a database is because I dont want to care about such issues. MVCC was created to prevent locking. If orientdb throws an excepction and breaks my operation it shows that MVCC is not implemented correctly.
Use of retry, locking or other mechanism is just “plug holes”. In my opinion the whole strategy of concurrency should be reviewed and standardized.
Very good paper: http://guide.couchdb.org/draft/consistency.html
@laa this error is correct but i need to remove all async update operation from my app to handle this issue . i think all users confused because there is lack of documentation about CRUD operation (such as our scenario for parallel updating ) in ODB. i suggest write more documentation about versioning of records in ODB . Thanks
Hi @saeedtabrizi , why do you think that this error is incorrect ?