如何在远程 OrientDB 上使用事务

How to use transactions on remote 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!

好的!这就解释了。所以我试试这个

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。

我找到了可能的解决方案。在一些帮助下 类 可能会扩大规模。

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());
}