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