Sailing中水线ODM中多个模型的回滚事务(适用于Mongo DB)

时间:2015-12-14 11:36:45

标签: mongodb transactions sails.js waterline sails-mongo

我正在使用Sails和Waterline ORM与Mongo数据库。

我有两个模型User和Profile with One to One关系 下面是我为Transaction with Rollback逻辑编写的代码。我认为可以有比这更好的逻辑,因为当前的逻辑非常笨拙。

问题:

  1. Waterline或Sails是否提供用于回滚目的的任何功能?
  2. 有没有更好的方法呢?

    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);
        })
      });
    

1 个答案:

答案 0 :(得分: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!
    }
})

我不知道它是否更好,但它似乎更具可读性,并且它处理三个写作阶段中的任何一个的错误。