简体   繁体   中英

How to use transactions on remote OrientDB

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM