2014-10-27 102 views
2

我想在多線程應用程序中使用orientdb內存中的實例。我看了很多代碼示例,但似乎沒有涵蓋這種情況。這裏是我的測試代碼:在多線程應用程序中使用內存中的orientdb

DbTest.java

public class DbTest { 
    public static void main(String [] args) { 
     ODatabaseDocumentTx db = new ODatabaseDocumentTx("memory:MyDb").create(); 

     Runnable myRunnable = new MyRunnable(db); 

     Thread thread = new Thread(myRunnable); 
     thread.start(); 
    } 
} 

MyRunnable.java

public class MyRunnable implements Runnable { 
    private ODatabaseDocumentTx db; 

    MyRunnable(ODatabaseDocumentTx db) { 
     this.db = db; 
    } 

    public void run() { 
     ODocument animal = new ODocument("Animal"); 
     animal.field("name", "Gaudi"); 
     animal.field("location", "Madrid"); 
     animal.save(); 
    } 
} 

這給了錯誤

異常的線程 「主題-3」 com.orientechnologies .orient.core.exception.ODatabaseException:數據庫實例未在當前線程中設置。確保將其設置爲:ODatabaseRecordThreadLocal.INSTANCE.set(db);

我讀,我應該嘗試使用連接池,但連接池似乎並不在線程「主要」 com.orientechnologies.orient內存數據庫的工作

ODatabaseDocumentTx db = ODatabaseDocumentPool.global().acquire("memory:MyDb", "admin", "admin"); 

異常.core.exception.OStorageException:無法打開本地存儲'MyDb'與模式= rw

任何想法如何這實際上應該工作?

回答

2

嘗試之前

ODatabaseDocumentTx db = new ODatabaseDocumentTx("memory:MyDb").create(); 

創建數據庫,然後使用池在你的線程

ODatabaseDocumentTx db = ODatabaseDocumentPool.global().acquire("memory:MyDb", "admin", "admin"); 
+0

這也工作正常,回想起來我應該意識到這是這兩個如何相互作用,謝謝。 – LeventisV2 2014-10-28 23:45:15

4

ODatabaseDocumentPool實例是線程安全的,可重複使用。 ODatabaseDocumentTx不是線程安全的,只能由單個線程使用。 OrientDB API在這裏有點難看,必須先創建內存數據庫,這是使用默認API無法實現的。但是,在使用內存數據庫時,並沒有任何意義。

所以在你的榜樣,最有效的方式做到這一點是:

public class OrientTest { 

static class MyRunnable implements Runnable { 

    @Override 
    public void run() { 
     // If using Java7+, use try-with-resources! 
     try (ODatabaseDocumentTx tx = getDatabase("memory:Test", "admin", "admin")) { 
      ODocument animal = tx.newInstance("Animal") 
       .field("name", "Gaudi") 
       .field("location", "Madrid"); 
      tx.save(animal); 
     } 
    } 

    private ODatabaseDocumentTx getDatabase(String url, String userName, String password) { 
     ODatabaseDocumentTx tx = new ODatabaseDocumentTx(url); 
     // database is not open yet! 
     if (!tx.exists()) { 
      // this will create AND open the database! 
      // Default credentials are "admin"/"admin" 
      tx.create(); 
      return tx; 
     } 
     return tx.open(userName, password); 
    } 

} 

public static void main(String[] args) { 
    new Thread(new MyRunnable()).start(); 
} 
} 
+0

我使它成爲一個靜態方法,因此可以調用它從任何地方加載數據庫連接。唯一奇怪的行爲是,當從構造函數中調用getDatabase()時,除非它以前在普通方法中調用(不管哪個線程),否則它似乎不會執行任何操作。我確信對此有一個完全合理的解釋,但無論它是做什麼的。 – LeventisV2 2014-10-28 23:42:33