orientechnologies / orientjs

The official fast, lightweight node.js client for OrientDB
http://orientdb.com
Other
326 stars 68 forks source link

How to use "runInTransaction" ? #343

Open petervavro opened 6 years ago

petervavro commented 6 years ago

I am sorry but I got a little bit confused. So, there is a new way how to use API transactions and that is described here. I am using transactions the way described here.

Could you please present an example how can I merge these properly ?

Thank you !

wolf4ood commented 6 years ago

Hi @petervavro

there is a main difference. Transactions as reported here works as a transactions builder. That means client side you generate a batch transaction using the APIs and then a single batch script is sent to the server (Old APIs but still valid in 3.0.x if you want to run a server side only tx).

Since OrientDB 3.0 server side (stateful) transactions are supported. That means with a given session you can do multiple request to the server and keep the transaction open and then commit when done with the new APIs

https://orientdb.org/docs//3.0.x/orientjs/OrientJS.html#transaction

RunInTransaction is an api helper that manage the begin/commit/and retry for you.

For example if you get a ConcurrentModificationException while committing the RunInTransaction will catch that for you and retry x time the given logic.

petervavro commented 6 years ago

Great , thank you , I really appreciate you explanation but I am sorry I still unsure how to use it. Here is an example :

BEGIN;
LET firstCreate = CREATE vertex TestTableB SET fieldB1="one";
LET secondCreate = CREATE vertex TestTableB SET fieldB1="two";
LET thirdCreate = CREATE vertex TestTableA SET fieldA1="something", linksetField = [$firstCreate,$secondCreate];
COMMIT ;
RETURN $thirdCreate ;

Could you please do us all a favor and rewrite this to JS example where you use "runInTransaction", so we can see how to use it.

I really appreciate that because for me in this case this would be more than thousand words :) 👍

Dr-Ing commented 4 years ago

I have the same question. Any luck finding an answer?

wolf4ood commented 4 years ago

Hi @petervavro @Dr-Ing

batch is different from runt in TX. You can either run a script like above which you can decide to run in a single batch tx with begin and commit.

Or you can use runtInTransaction API, which will run all the command/query in a transaction.(begin/commit/retry) with retry in caso fo MVCC exception. Like this example

try {
    let results = await session.runInTransaction(async tx => {
      let first = await tx.command("create vertex V set name = 'First'").all();
      let second = await tx
        .command("create vertex V set name = 'Second'")
        .all();

      let edge = await tx
        .command("create Edge from :from to : to", {
          params: {
            from: first[0]["@rid"],
            to: second[0]["@rid"]
          }
        })
        .all();
      return edge;
    });
    console.log(results);
  } catch (e) {
    console.log(e);
  }

Let me know if this helps

Dr-Ing commented 4 years ago

great. Works like a charm. 👍

It would be really useful if such a nice example is included in the documentation. The multiple use of the tx in the try block is not intuitive, and the params structure first[0]["@rid"] is also not obvious. Also one example with UPDATE UPSERT RETURN will be a useful addition to the documentation as the returned object is [{count:xx}] by default. thanks!