如何在远程OrientDB

时间:2016-11-23 12:51:40

标签: java transactions orientdb

TL; DR 当从Java服务器使用远程OrientDB数据库时,如何在事务中执行SQL命令?

长版

我有一个从java服务器连接的远程OrientDB数据库。

我在OrientDB文档中读到,要启动事务,我调用db.begin(),在数据库更新后,我调用db.commit()db.rollback()

所以这最初是我试图做的事情:

try {
  db.begin();
  db.command(new OCommandSQL('delete edge connected from #10:1')).execute();
  db.command(new OCommandSQL('create edge connected from #10:1 to BROKEN_SQL')).execute();
  db.commit();
} catch (Throwable e) {
  db.rollback();
}

那不起作用。它删除了边缘(在提交之前)。按预期在创建边缘线上引发异常但未回滚。然后我在文档中读到了

NOTE: OrientDB keeps the transaction on client RAM

客户端内存;这意味着在调用db.commit()之前,数据库服务器完全不知道java服务器正在做什么。

这不是我发生的事情,当单步执行代码时,每个命令确实在服务器上执行,而db.begin()db.rollback()没有任何效果。然后我读了

SQL commands are always executed on the server side. 
They don't care if you're in the middle of a transaction on the client side!

OK!这解释了它。所以我试试这个

try {
  db.command(new OCommandSQL('begin')).execute();
  db.command(new OCommandSQL('delete edge connected from #10:1')).execute();
  db.command(new OCommandSQL('create edge connected from #10:1 to BROKEN_SQL')).execute();
  db.command(new OCommandSQL('commit')).execute();
} catch (Throwable e) {
  db.command(new OCommandSQL('rollback')).execute();
}

立即失败:

Request processing failed; nested exception is com.orientechnologies.orient.core.command.OCommandExecutorNotFoundException:
Cannot find a command executor for the command request: sql.begin

但我使用db.save(o)db.delete(o)和交易成功了。一切似乎与文档一致。但是,如何确保在事务中完成 SQL命令 。我不在乎交易是在客户端还是服务器上。我尝试过使用OrientDB 2.1.13,2.1.15和2.1.25。

1 个答案:

答案 0 :(得分:0)

我找到了一个可能的解决方案。通过一些帮助类,可以将其扩展。

StringBuilder query = new StringBuilder();
query.append("begin\n");
things.forEach((thing) -> {
  query.append("delete edge owner from " + thing.getId() + "\n");
  query.append("create edge owner from " + thing.getId() + " to " + newOwner.getId() + "\n");
});
query.append("commit\n");

try {
  db.command(new OCommandScript(query)).execute()
} catch (Throwable t) {
  logger.error(t.toString());
}