Search code examples
sails.jsorientdbwaterlinesails-orientdb

Transaction in orientdb and waterline


I am trying to to create transaction in waterline but I am getting this error from OrientDB:

com.orientechnologies.orient.core.command.OCommandExecutorNotFoundException: Cannot find a command executor for the command request: sql.BEGIN

Here is my code:

 try {
  itemsModel.query("BEGIN", function(err) { if (err) {throw new Error(err);}
    itemsModel.update({id:items_ids,status:ACTIVE},{status:INACTIVE})
      .exec(function(err, INA_items){ if (err) {throw new Error(err);}
        if (INA_items.length != items_ids.length ) {throw new Error({err:RECORD_NOT_FOUND});}
        itemsModel.query("COMMIT", function(err) { if (err) {throw new Error({err:MSG.RECORD_NOT_FOUND,title:"ITEMS"});} });
      });
  });
}
catch(e){
  itemsModel.query("ROLLBACK", function(err) { 
    if (err) {return res.serverError(err);}
    return res.serverError(e);  
  });
}

I also checked BEGIN command directly in orientdb, but same error.


Solution

  • The question as it stands is mixing several different concepts, I'll try to address one by one:

    1. Waterline's API itself does not support transactions (check issue #755);

    2. It looks like you are using sails-orientdb adapter and from it you are executing a raw SQL query;

    3. The SQL query you are executing in the second line of your example is just BEGIN and that's where OrientDB itself is throwing an error. A transaction SQL query must be something like:

      begin
      let account = create vertex Account set name = 'Luke'
      let city = select from City where name = 'London'
      let edge = create edge Lives from $account to $city
      commit retry 100
      return $edge
      

      Example taken from OrientDB docs.

    4. Alternatively you can use transactions in a more javascript style by making use of the Oriento DB object. Assuming you are using sails-orientdb you can get the Oriento DB object like this:

      var db = itemsModel.getDB();
      
      // using oriento syntax, you can do something like
      var tx = db.begin();
      tx.create({
        '@class': 'TestClass',
        name: 'item3'
      });
      return tx.commit()
      .then(function (results) {
        console.log(results.created.length);  // should be 1
      });
      

      Example taken from Oriento tests. Another good example can be found at Oriento's example folder.