Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make transactions with sails.js/waterline?

I am trying to put my queries into transaction and I am failing in runtime. Error I am getting is :

Object #<bound> has no method 'transaction'

I tried to follow this "documentation".

In short my model looks like that :

updateOrCreate: function (profile_id, positive,negative) {
  var deferred = Q.defer();

  Reputation.transaction().findOne().where({profile: profile_id}).then(function (rep) {
    if (rep) {
      // Reputation logic

      rep.save(function (err) {deferred.resolve();});
    } else {
      // Reputation does not exist. Create.
      Reputation.create({profile: profile_id, positive: positive,negative:negative}).exec(function (e, rep) {
        deferred.resolve();});
    }
  }).fail(function (err) {deferred.reject()});

  return deferred.promise;
}

any ideas what did I do wrong?

thanks.

w.

like image 563
wonglik Avatar asked Jan 15 '15 11:01

wonglik


People also ask

What is waterline in sails JS?

Sails comes installed with a powerful ORM/ODM called Waterline, a datastore-agnostic tool that dramatically simplifies interaction with one or more databases.

How do you use sails in JavaScript?

Creating a new Sails application To create a new Sails application, run the sails new command passing in the name of your application. This command will both generate a new Sails app and run npm install to install all dependencies for you.

How do you populate in sails JS?

populate() Modify a query instance so that, when executed, it will populate child records for the specified collection, optionally filtering by subcriteria . Populate may be called more than once on the same query, as long as each call is for a different association.

Is sails JS framework?

Sails is the most popular MVC framework for Node. js, designed to emulate the familiar MVC pattern of frameworks like Ruby on Rails, but with support for the requirements of modern apps: data-driven APIs with a scalable, service-oriented architecture.


1 Answers

This is now supported in sails v1 (not official release yet at June 26, 2017). You can follow this link for documentation in next.sailsjs.com: Datastore.transaction()

In doc above is the following example:

sails.getDatastore()
.transaction(function (db, proceed) {

  BankAccount.findOne({ owner: req.session.userId }).usingConnection(db)
  .exec(function (err, myAccount) {
    if (err) { return proceed(err); }
    if (!myAccount) { return proceed(new Error('Consistency violation: Database is corrupted-- logged in user record has gone missing')); }

    BankAccount.findOne({ owner: req.param('recipientId') }).usingConnection(db)
    .exec(function (err, recipientAccount) {
      if (err) { return proceed(err); }
      if (!recipientAccount) {
        err = new Error('There is no recipient with that id');
        err.code = 'E_NO_SUCH_RECIPIENT';
        return proceed(err);
      }

      // Do the math to subtract from the logged-in user's account balance,
      // and add to the recipient's bank account balance.
      var myNewBalance = myAccount.balance - req.param('amount');

      // If this would put the logged-in user's account balance below zero,
      // then abort.  (The transaction will be rolled back automatically.)
      if (myNewBalance < 0) {
        err = new Error('Insufficient funds');
        err.code = 'E_INSUFFICIENT_FUNDS';
        return proceed(err);
      }

      // Update the current user's bank account
      BankAccount.update({ owner: req.session.userId })
      .set({
        balance: myNewBalance
      })
      .usingConnection(db)
      .exec(function (err) {
        if (err) { return proceed(err); }

        // Update the recipient's bank account
        BankAccount.update({ owner: req.param('recipientId') })
        .set({
          balance: recipientAccount.balance + req.param('amount')
        })
        .usingConnection(db)
        .exec(function (err) {
          if (err) { return proceed(err); }
          return proceed();
        });
      });
    });
  });

}).exec(function(err){
  // At this point, we know that, if our code above passed through
  // an error to `proceed`, Sails took care of rolling back the
  // transaction.  Otherwise, it committed it to the database.
  if (err && err.code === 'E_INSUFFICIENT_FUNDS') {
    return res.badRequest(err);
  }
  else if (err && err.code === 'E_NO_SUCH_RECIPIENT') {
    return res.notFound();
  }
  else if (err) {
    return res.serverError(err);
  }

  // All done!
  return res.ok();

});
like image 74
edrian Avatar answered Nov 15 '22 02:11

edrian