How to use transactions on remote OrientDB

只谈情不闲聊 提交于 2019-12-25 09:16:57

问题


TL;DR How do I make SQL commands execute in a transaction when using a remote OrientDB database from a java server?

Long version

I have a remote OrientDB database that I connect to from a java server.

I read in the OrientDB documentation that to start a transaction I call db.begin() and after the database updates I call db.commit() or db.rollback().

So this is initially what I was trying to do:

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

That didn't work. It deleted the edge (before it was commit). Threw an exception on the create edge line as expected but did not rollback. I then read in the documentation that

NOTE: OrientDB keeps the transaction on client RAM

client RAM; Meaning that the database server is completely unaware of what the java server is doing until db.commit() is called.

That is not what happened to me and when stepping through the code each command is indeed executed on the server and db.begin() and db.rollback() has no effect whatsoever. Then I read

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! That explains it. So I try this

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

Which immediately fails with:

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

I do however have success using db.save(o) or db.delete(o) and transactions. Everything appears to align with documentation. But how do I make sure my SQL commands are done in a transaction. I do not care if the transaction is on the client or server. I've tried with OrientDB 2.1.13, 2.1.15 and 2.1.25.


回答1:


I found a possible solution. With some help classes it might be possible to get it to scale.

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


来源:https://stackoverflow.com/questions/40765065/how-to-use-transactions-on-remote-orientdb

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!