Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OConcurrentModificationException while creating relations between verticies #3761

Closed
vladmlch opened this issue Mar 13, 2015 · 4 comments
Closed
Assignees
Labels

Comments

@vladmlch
Copy link

I created one instance of class Car with name "Mercedes" and want to create a relation between this car and two instances of class Person. Test throws an exception: OConcurrentModificationException. How can I avoid it and create as many edges as I want from many Persons to the same vertex Car?

Thanks, Vlad

    @Test
    public void testInsertFromDifferentThreads() throws InterruptedException {

    int threadsCount = 2;
    ExecutorService service = Executors.newFixedThreadPool(threadsCount);

    OrientGraph t1 = factory.graph();
    t1.begin();
    t1.getVerticesOfClass("Person").forEach(t1::removeVertex);
    t1.commit();

    t1.begin();
    OrientVertex mercedes = t1.addVertex("class:Car");
    mercedes.setProperty("name", "Mercedes");
    t1.commit();

    final CountDownLatch threadLatch = new CountDownLatch(threadsCount);
    final CountDownLatch mainLatch = new CountDownLatch(threadsCount);

    for (int i = 0; i < threadsCount; i++) {
        service.execute(() -> {
            ODatabaseDocumentTx tx = factory.openDatabase();
            ODatabaseRecordThreadLocal.INSTANCE.set(tx);

            OrientGraph t2 = factory.graph();
            t2.begin();

            OrientVertex luca = t2.addVertex("class:Person");
            luca.setProperty("name", "Luca");

            Vertex mercedes1 = t2.getVertices("Car.name", "Mercedes").iterator().next();
            luca.addEdge("Owns", mercedes1);

            threadLatch.countDown();
            try {
                threadLatch.await();
                t2.commit();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            } finally {
                mainLatch.countDown();
            }
        });
    }
    mainLatch.await();

    assertEquals(threadsCount, t1.countVertices("Person"));
}

Stacktrace:

Exception in thread "pool-3-thread-1" com.orientechnologies.orient.core.exception.OConcurrentModificationException: Cannot UPDATE the record #32:2 because the version is not the latest. Probably you are updating an old record or it has been modified by another user (db=v62 your=v61)
at com.orientechnologies.orient.core.conflict.OVersionRecordConflictStrategy.checkVersions(OVersionRecordConflictStrategy.java:55)
at com.orientechnologies.orient.core.conflict.OVersionRecordConflictStrategy.onUpdate(OVersionRecordConflictStrategy.java:42)
at com.orientechnologies.orient.core.storage.impl.local.OAbstractPaginatedStorage.checkAndIncrementVersion(OAbstractPaginatedStorage.java:2020)
at com.orientechnologies.orient.core.storage.impl.local.OAbstractPaginatedStorage.doUpdateRecord(OAbstractPaginatedStorage.java:1657)
at com.orientechnologies.orient.core.storage.impl.local.OAbstractPaginatedStorage.commitEntry(OAbstractPaginatedStorage.java:2105)
at com.orientechnologies.orient.core.storage.impl.local.OAbstractPaginatedStorage.commit(OAbstractPaginatedStorage.java:917)
at com.orientechnologies.orient.core.tx.OTransactionOptimistic.doCommit(OTransactionOptimistic.java:483)
at com.orientechnologies.orient.core.tx.OTransactionOptimistic.commit(OTransactionOptimistic.java:147)
at com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx.commit(ODatabaseDocumentTx.java:2376)
at com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx.commit(ODatabaseDocumentTx.java:2346)
at com.orientechnologies.orient.server.network.protocol.binary.ONetworkProtocolBinary.commit(ONetworkProtocolBinary.java:1087)
at com.orientechnologies.orient.server.network.protocol.binary.ONetworkProtocolBinary.executeRequest(ONetworkProtocolBinary.java:389)
at com.orientechnologies.orient.server.network.protocol.binary.OBinaryNetworkProtocolAbstract.execute(OBinaryNetworkProtocolAbstract.java:220)
at com.orientechnologies.common.thread.OSoftThread.run(OSoftThread.java:69)

@lvca lvca added this to the 2.0.6 milestone Mar 13, 2015
@vladmlch
Copy link
Author

Is there any updates with this issue?

@lvca
Copy link
Member

lvca commented Mar 15, 2015

@profic This seems the classic case where you should manage the exception and retry. Isn't it?

@vladmlch
Copy link
Author

Ok, now I catch an eception and retry again. When O run test for 1000 records, I get about 200 concurrent modification exception, but when I run test second time and try to add more edges and vertices, there are no exceptions at all and the version of single vertex to which I create edges does'n increment.

@tglman
Copy link
Member

tglman commented Mar 20, 2015

@profic this is due to the use of the (ridbag)[http://www.orientechnologies.com/docs/last/RidBag.html] if you set RID_BAG_EMBEDDED_TO_SBTREEBONSAI_THRESHOLD to 0 this should never happen but be aware that is a database settings and you may don't want this behaviour in other classes, just read the documentation for more info ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

3 participants