Search code examples
node.jsneo4jneo4j-node

Neo4j transaction misunderstanding


While I was looking over the documentation for transactions I came accross on this example:

var tx = session.beginTransaction();
tx.run("MERGE (bob:Person {name : {nameParam} }) RETURN bob.name AS name", {nameParam: 'Bob'})
  .subscribe({
    onNext: function (record) {
      console.log(record.get('name'));
    },
    onCompleted: function () {
      session.close();
    },
    onError: function (error) {
      console.log(error);
    }
  });

//decide if the transaction should be committed or rolled back
var success = false;

if (success) {
  tx.commit()
    .subscribe({
      onCompleted: function () {
        // this transaction is now committed 
      },
      onError: function (error) {
        console.log(error);
      }
    });
} else {
  //transaction is rolled black and nothing is created in the database
  console.log('rolled back');
  tx.rollback();
}

But on snippet above it does not seem to change the success somehow I mean how it does determine whetherthe transaction sucessfully executed or not the success variable does not change the value at all.


Solution

  • It's because you are calling session.close() on the onCompleted callback function.

    When you close a session, it will automatically commit all the underlying opened transactions.

    Moreover on your example, you are not waiting that the tx.run promise is finished or not. you should do it on the section decide if the transaction should be committed or rolled back

    So you should do something like that :

        var driver = neo4j.v1.driver("bolt://localhost",  neo4j.v1.auth.basic("neo4j", "neo4j"), { encrypted:false });
        var session = driver.session();
        // run statement in a transaction
        var tx = session.beginTransaction();
        tx.run("MERGE (bob:Person {name : {nameParam} }) RETURN bob.name AS name", {nameParam: 'Bob'})
          .subscribe({
            onNext: function (record) {
              console.log(record.get('name'));
            },
            onCompleted: function () {
              console.log('statement completed')
            },
            onError: function (error) {
              console.log(error);
            }
          });
    
        //decide if the transaction should be committed or rolled back
        var success = true;
    
        if (success) {
          tx.commit()
            .subscribe({
              onCompleted: function () {
                // this transaction is now committed 
              },
              onError: function (error) {
                console.log(error);
              }
            });
        } else {
          //transaction is rolled black and nothing is created in the database
          console.log('rolled back');
          tx.rollback();
        }
        session.close();
    

    PS: I will contact the dev team to update the example