Транзакция отката для нескольких моделей в ODM Waterline в Sails (для Mongo DB)

Я использую Sails и Waterline ORM с базой данных Mongo.

У меня есть две модели «Пользователь» и «Профиль» с отношением «один к одному».
Ниже приведен код, который я написал для транзакции с логикой отката. Я думаю, что может быть гораздо лучшая логика, чем эта, поскольку текущая логика очень неуклюжа.

Вопросы :

  1. Предоставляют ли Waterline или Sails какую-либо функциональность для отката?

Есть ли лучший способ сделать это?

User.create(newUser).then(function (data) {
    var newProfile = {
        displayName: data.name,
        email: data.email,
        user: data._id
    }
    return Profile.create(newProfile);
  }).then(function (profileData) {
    sails.log.info("Profile Data " + JSON.stringify(profileData));

    // Update the user with Profile Info
    User.update(newUser._id, {profile: profileData._id}).then(function (updatedUser) {
      return updatedUser;
    }, function (err) {
      // TODO Rollback logic if the User Updation Fails
    })
  }, function (err) {
    sails.log.error("Failed to Create Profile for the User . Deleting the created User");
    var criteria = {
      email: data.email
    }
    User.destroy(criteria).then(function (user) {
      sails.log.error("Deleted the Created User " + JSON.stringify(user));
      throw new Error("ERROR CREATING User");
    }, function (err) {
      sails.log.error("ERROR DELETING USER");
      throw new Error("ERROR DELETING USER", err);
    })
  });

person Shiva MSK    schedule 14.12.2015    source источник


Ответы (1)


На вопрос 1: нет.

У меня возникло бы желание сделать что-то вроде этого:

async.waterfall([
    function(callback){
        User.create(newUser).then(function(data){       
            callback(null, data);
        })
        .catch(function(err){
            callback(err, null, null); // don't need to rollback anything
        })
    },
    function(data, callback){
        Profile.create({
            displayName: data.name,
            email: data.email,
            user: data._id
        })
        .then(function(profile){
            callback(null, data, profile)
        })
        .create(function(err){
            callback(err, data._id, null); // only need user's id
        })
    },
    function(userData, profileData, callback){
        User.update(userData._id, {profile: profileData._id})
            .then(function(updatedUser){
                callback(null, updatedUser);
            })
            .catch(function(err){
                callback(err, userData._id, profileData._id); // can roll back both
            })
    }
], function(err, userData, profileData){
    if(err) {
        sails.log.error(err);
        // do rollback, userData is user's ID, profileData is profile id
        // if either one is undefined, then it doesn't exist
    } else {
        // userData is user object from the last update, return it!
    }
})

Я не знаю, лучше ли это, но кажется более читабельным, и он обрабатывает ошибки для любого из трех этапов написания.

person Community    schedule 17.12.2015