对比Thinkjs transaction vs. hooks

477 阅读1分钟

假设有两个表格,一个是充值chongzhi,一个是交易记录jiaoyi,如果充值成功,更改充值status为成功confirmed,此时需要添加一条交易记录,同时更改用户余额。

两个做法:

一. 利用transaction

1.更新充值status 2.添加交易记录 3.更新用户余额

如果有一个操作错误,则roll back;如果没错则commit

module.exports = class extends think.Model {
  async updateData(data){
    const result = await this.transaction(async () => {
      const insertId = await this.add(data);
      // 通过 db 方法让 user_cate 模型复用当前模型的数据库连接
      const userCate = this.model('user_cate').db(this.db());
      let result = await userCate.add({user_id: insertId, cate_id: 100});
      return result;
    })
  }
}

二.利用hooks

  1. 更新(update)充值status
  2. afterUpdate里面添加交易记录和更新用户余额
afterUpdate(data) {
    super.afterUpdate(data);
    console.log("data", data);
    //do something...
    try {
        this.model("payment").add({
        userId: 1,
        type: -1,
        amount: 23,
        balance: 234,
        remark: data.remark
      });

        this.model("charge").add({
        userId: 1,
        status: -1,
        money: 123,
        method: "test1",
        remark: data.remark
        // serial:'rr466'
      });
    } catch (error) {
      throw new Error(error);
    }
  } 

问题:afterUpdate如果用async await则会阻塞停止;不管try catch error如何,不管添加记录有没有问题则不影响第1步的操作,因此没有roll back机制,显然不适合做交易。

结论:hooks适合于发email等非严格关联类操作,不适合做交易和关联表格操作,除非关联表格操作不是很重要,比如afterFind后更新流量博客数量。