在多线程应用程序中使用内存中的orientdb

时间:2014-10-27 23:55:15

标签: java multithreading orientdb in-memory-database

我正在尝试在多线程应用程序中使用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);

我读到我应该尝试使用连接池,但连接池似乎不适用于内存数据库

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

线程中的异常" main" com.orientechnologies.orient.core.exception.OStorageException:无法打开本地存储' MyDb'模式= rw

任何想法如何实际应该起作用?

2 个答案:

答案 0 :(得分: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();
}
}

答案 1 :(得分:2)

尝试在

之前创建数据库
ODatabaseDocumentTx db = new ODatabaseDocumentTx("memory:MyDb").create();

然后在你的线程中使用池

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