我正在尝试在多线程应用程序中使用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
任何想法如何实际应该起作用?
答案 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");