处理嵌套事务的简单方法

罗恩

假设有一个“ addUser”函​​数,我们需要在其中向“ Account”表和“ User”表插入一条记录,因此这两个步骤也必须在事务内,因此我们将编写以下代码:

function addUser (userName, password) {
    sequelize.transaction(function () {
        return AccountModel.create(...)
        .then(UserModel.create(...))    
    })
}

但是,在另一个“ addTeam”函数中,我们需要在内部向“ Team”表中插入一条记录,并使用上述函数创建一个admin用户。该功能还需要包装在事务中。

因此问题来了,“ addUser”功能有时需要开始一个新的事务,有时需要使用传入的事务。最明显的方法如下:

function addUser (userName, password, transaction) {
       let func = function (t) {
           return  AccountModel.create(..., t)
           .then(()=>UserModel.create(..., t)));
       if (transaction) func(t);
       else sequelize.transaction(x=>func(t));
}

function addTeam() {
     sequelize.transaction(x=> {
         TeamModel.create(..., x)
         .then(y=>addUser(x));
     });
}

显然,这很糟糕。如何轻松处理它,这使事务对调用方完全透明,如下所示:

@Transaction
async function addUser(userName, password) {
    await AccountModel.create(...);
    await UserModel.create(...);
}

@Transaction
async function addTeam(...) {
    await TeamModel.create(...);
    await addUser(...);
} 
罗恩

我解决了问题,感觉很好。

我使用了sequelize提供的CLS功能,例如下面的代码:

let namespace = Sequelize.cls = cls.createNamespace('myschool');
export const db = new Sequelize(config.db.url);

export const trans = option => operation => async function () {
    let t = namespace.get('transaction');
    let hasTrans = !!t;
    t = t  || await db.transaction();
    try {
        let result = await operation.apply(null, arguments);
        if (!hasTrans) await t.commit();
        return result;
    }
    catch (e) {
        if (!hasTrans) await t.rollback();
        throw e;
    }
};

上面的代码只是创建一个事务,如果本地上下文中没有事务,则提交该事务,否则将其保留。

而每个要交易的业务功能只需使用上面的高阶功能来包装,如下所示:

export const createSchool = trans()( async (name, accountProps) => {
    let school = await SchoolModel.create({name});
    let teacher = await createTeacher({...accountProps, schoolId: school.get('id')});
    return {school, teacher};
});

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

比较处理器的简单方法

来自分类Dev

TypeScript:初始化嵌套对象的更简单方法?

来自分类Dev

使用HTML代码处理XML的简单方法?

来自分类Dev

处理类中事件的最简单方法

来自分类Dev

使用主题和队列处理@JmsListener的更简单方法

来自分类Dev

处理字母和数字组合的简单方法

来自分类Dev

将死信发送回处理主题的最简单方法?

来自分类Dev

处理类中事件的最简单方法

来自分类Dev

导出javadocs的简单方法

来自分类Dev

选择文件的简单方法

来自分类Dev

分配矩阵的简单方法

来自分类Dev

复制文件的简单方法

来自分类Dev

导出javadocs的简单方法

来自分类Dev

选择文件的简单方法

来自分类Dev

移动公式的简单方法

来自分类Dev

在Ebean中创建嵌套对象的最简单方法是什么?

来自分类Dev

在Grpc生成的Java代码中设置嵌套属性值的更简单方法

来自分类Dev

为嵌套关联生成多个字段集的最简单方法?

来自分类Dev

在Ebean中创建嵌套对象的最简单方法是什么?

来自分类Dev

为嵌套 for 循环最大化 CPU 使用率的最简单方法是什么?

来自分类Dev

计算服务器正在处理的请求的简单方法是什么?

来自分类Dev

使用预处理器宏构造用于引发std :: exception的信息消息的简单方法

来自分类Dev

从UIButton新闻处理程序获取关联的UIView的最简单方法

来自分类Dev

后期处理是否提供应用一组方面的简单方法

来自分类Dev

在Pandas中通过多处理读取csv文件的最简单方法

来自分类Dev

使用javascript以管理员身份运行批处理的简单方法

来自分类Dev

在Haskell中处理非确定性的最简单方法?

来自分类Dev

在网页设计中处理拼图菜单的最简单方法

来自分类Dev

使用预处理器宏构造用于引发std :: exception的信息消息的简单方法

Related 相关文章

  1. 1

    比较处理器的简单方法

  2. 2

    TypeScript:初始化嵌套对象的更简单方法?

  3. 3

    使用HTML代码处理XML的简单方法?

  4. 4

    处理类中事件的最简单方法

  5. 5

    使用主题和队列处理@JmsListener的更简单方法

  6. 6

    处理字母和数字组合的简单方法

  7. 7

    将死信发送回处理主题的最简单方法?

  8. 8

    处理类中事件的最简单方法

  9. 9

    导出javadocs的简单方法

  10. 10

    选择文件的简单方法

  11. 11

    分配矩阵的简单方法

  12. 12

    复制文件的简单方法

  13. 13

    导出javadocs的简单方法

  14. 14

    选择文件的简单方法

  15. 15

    移动公式的简单方法

  16. 16

    在Ebean中创建嵌套对象的最简单方法是什么?

  17. 17

    在Grpc生成的Java代码中设置嵌套属性值的更简单方法

  18. 18

    为嵌套关联生成多个字段集的最简单方法?

  19. 19

    在Ebean中创建嵌套对象的最简单方法是什么?

  20. 20

    为嵌套 for 循环最大化 CPU 使用率的最简单方法是什么?

  21. 21

    计算服务器正在处理的请求的简单方法是什么?

  22. 22

    使用预处理器宏构造用于引发std :: exception的信息消息的简单方法

  23. 23

    从UIButton新闻处理程序获取关联的UIView的最简单方法

  24. 24

    后期处理是否提供应用一组方面的简单方法

  25. 25

    在Pandas中通过多处理读取csv文件的最简单方法

  26. 26

    使用javascript以管理员身份运行批处理的简单方法

  27. 27

    在Haskell中处理非确定性的最简单方法?

  28. 28

    在网页设计中处理拼图菜单的最简单方法

  29. 29

    使用预处理器宏构造用于引发std :: exception的信息消息的简单方法

热门标签

归档