2015-09-21 17 views
5

Orientdb'yi (v2.1.2) çok parçalı bir ortamdan (Java 8) kullanmaya çalışıyorum. Orientdb'in MVCC kullandığını ve bu işlemlerin başarısız olabileceğini ve tekrar çalıştırılması gerektiğinin farkındayım.Java'da OrientDB eşzamanlı grafik işlemleri

Bu tür durumları provoke etmeye çalışan küçük bir ünite testi yazdım ve çatalı dişler içinde döngüsel bir bariyer bekleyerek.

Sep 21, 2015 3:00:24 PM com.orientechnologies.common.log.OLogManager log 
INFO: OrientDB auto-config DISKCACHE=10,427MB (heap=3,566MB os=16,042MB disk=31,720MB) 
Thread [0] running 
Thread [1] running 
Sep 21, 2015 3:00:24 PM com.orientechnologies.common.log.OLogManager log 
WARNING: {db=tinkerpop} Requested command 'create edge type 'testedge_1442840424480' as subclass of 'E'' must be executed outside active transaction: the transaction will be committed and reopen right after it. To avoid this behavior execute it outside a transaction 
Sep 21, 2015 3:00:24 PM com.orientechnologies.common.log.OLogManager log 
WARNING: {db=tinkerpop} Requested command 'create edge type 'testedge_1442840424480' as subclass of 'E'' must be executed outside active transaction: the transaction will be committed and reopen right after it. To avoid this behavior execute it outside a transaction 
Exception in thread "Thread-4" com.orientechnologies.orient.core.exception.OSchemaException: Cluster with id 11 already belongs to class testedge_1442840424480 
    at com.orientechnologies.orient.core.metadata.schema.OSchemaShared.checkClustersAreAbsent(OSchemaShared.java:1264) 
    at com.orientechnologies.orient.core.metadata.schema.OSchemaShared.doCreateClass(OSchemaShared.java:983) 
    at com.orientechnologies.orient.core.metadata.schema.OSchemaShared.createClass(OSchemaShared.java:415) 
    at com.orientechnologies.orient.core.metadata.schema.OSchemaShared.createClass(OSchemaShared.java:400) 
    at com.orientechnologies.orient.core.metadata.schema.OSchemaProxy.createClass(OSchemaProxy.java:100) 
    at com.tinkerpop.blueprints.impls.orient.OrientBaseGraph$6.call(OrientBaseGraph.java:1387) 
    at com.tinkerpop.blueprints.impls.orient.OrientBaseGraph$6.call(OrientBaseGraph.java:1384) 
    at com.tinkerpop.blueprints.impls.orient.OrientBaseGraph.executeOutsideTx(OrientBaseGraph.java:1739) 
    at com.tinkerpop.blueprints.impls.orient.OrientBaseGraph.createEdgeType(OrientBaseGraph.java:1384) 
    at com.tinkerpop.blueprints.impls.orient.OrientBaseGraph.createEdgeType(OrientBaseGraph.java:1368) 
    at com.tinkerpop.blueprints.impls.orient.OrientBaseGraph.createEdgeType(OrientBaseGraph.java:1353) 
    at com.tinkerpop.blueprints.impls.orient.OrientVertex.addEdge(OrientVertex.java:928) 
    at com.tinkerpop.blueprints.impls.orient.OrientVertex.addEdge(OrientVertex.java:832) 
    at com.gentics.test.orientdb.OrientDBTinkerpopMultithreadingTest.lambda$0(OrientDBTinkerpopMultithreadingTest.java:31) 
    at com.gentics.test.orientdb.OrientDBTinkerpopMultithreadingTest$$Lambda$1/1446001495.run(Unknown Source) 
    at java.lang.Thread.run(Thread.java:745) 

testi basit bellek içi veri tabanını kullanıyor: Maalesef Test anlamıyorum bilinmeyen bir özel durum ile başarısız olur. Ben orientdb bazı küme eylemlerini kontrol neden alamadım:

Cluster with id 11 already belongs to class testedge

nasılsa bu sorun yalnızca görünen i aynı etikete sahip iki kenarları oluşturmaya çalıştığınızda.
private OrientGraphFactory factory = new OrientGraphFactory("memory:tinkerpop").setupPool(5, 20); 

@Test 
public void testConcurrentGraphModifications() throws InterruptedException { 
    OrientGraph graph = factory.getTx(); 
    Vertex v = graph.addVertex(null); 
    graph.commit(); 
    CyclicBarrier barrier = new CyclicBarrier(2); 

    List<Thread> threads = new ArrayList<>(); 

    // Spawn two threads 
    for (int i = 0; i < 2; i++) { 
     final int threadNo = i; 
     threads.add(run(() -> { 
      System.out.println("Running thread [" + threadNo + "]"); 
      // Start a new transaction and modify vertex v 
      OrientGraph tx = factory.getTx(); 
      Vertex v2 = tx.addVertex(null); 
      v.addEdge("testedge", v2); 
      try { 
       barrier.await(); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
      tx.commit(); 
     })); 
    } 

    // Wait for all spawned threads 
    for (Thread thread : threads) { 
     thread.join(); 
    } 
} 

protected Thread run(Runnable runnable) { 
    Thread thread = new Thread(runnable); 
    thread.start(); 
    return thread; 
} 

testcase için tam kaynaklardan

burada bulunabilir: Genel olarak

https://github.com/Jotschi/orientdb-concurrency-test/blob/master/src/test/java/com/gentics/test/orientdb/OrientDBTinkerpopMultithreadingTest.java#L18

i bir in orientdb kullanırken MVCC çatışmaları nasıl başa gösteren bir örnek çok memnun olurum gömülü çok iş parçacıklı java ortamı.


Güncelleme: Ben tx.getVertex (vertex.getId()) aracılığıyla benim iplik içindeki köşe yeniden sorun artık occures fark

(değil .reload yoluyla()) . Ben vertex nesne başvurusu sadece iş parçacığım geçirip orada kullanıyorum çeşitli hatalar alıyorum. OrientVertex sınıfının threadafe olmadığını varsayalım.

cevap

4
  1. Hepiniz grafik elemanları iş parçacığı güvenli olmayan haklısın.
  2. Kenar oluşturduğunuzda özel durumunuzun sebebi aşağıdadır; grafik veritabanının altında, kenar etiketine eşit olan bir belge ile belge oluşturabilirsiniz. Sınıf eksikse otomatik olarak işlem yapılır ve şema içinde yeni sınıf oluşturulur. Aynı sınıfa aynı anda ve aynı küme oluşturulduğunda aynı anda kenarlar eklediğinizde, her sınıf veritabanında kümelenecek şekilde eşleştirilir (bir tablo gibidir). Böylece bir iş parçacığı diğerini kazanır, bu, belirtilen ada sahip kümenin oluşturduğu istisna ile başarısız olur. Aslında, çalışma zamanlarında kenarlar eklemeden önce mümkünse tüm sınıfların kenar etiketlerini oluşturmanızı öneririm.

Bir öneri daha. OrientGraph örneğini sunucuya bağlantı gibi düşünmelisiniz. En iyi kullanım takip ediyor:

  1. Kurulum havuz OrientGraphFactory içinde
  2. Edinme grafiği örneği işlem öncesi.
  3. İşlemi gerçekleştirin.
  4. Ara .shutdown(), uzun ömürlü grafik örnekleri oluşturmayın.