如何在远程 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());
}
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());
}