收藏
回答

云数据库开发中的事务处理这个例子感觉不对呀,太困惑了,能帮忙看看吗?

https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-sdk-api/database/Database.startTransaction.html

如上面的链接提供的例子。这个里边给出的例子是从A用户转10元给B用户,如果用事务的的话,应该是在操作A-10完成,B+10失败的时候才需要进行事务的rollback呀?为啥例子中是查找A,B账号中某一个不存在就进行rollback? 而没有放在A-10,B+10这两个成功与否上?另外,如果try里边的操作如果发生异常(例如:恰巧是A-10操作完成了,而B+10操作抛异常),被catch 捕获到,那么这个时候不应该进行rollback 吗?



const cloud = require('wx-server-sdk')
cloud.init({
  env: cloud.DYNAMIC_CURRENT_ENV
})
const db = cloud.database({
  throwOnNotFound: false,
})
const _ = db.command

exports.main = async (event) => {
  try {
    const transaction = await db.startTransaction()

    const aaaRes = await transaction.collection('account').doc('aaa').get()
    const bbbRes = await transaction.collection('account').doc('bbb').get()

    if (aaaRes.data && bbbRes.data) {
      const updateAAARes = await transaction.collection('account').doc('aaa').update({
        data: {
          amount: _.inc(-10)
        }
      })

      const updateBBBRes = await transaction.collection('account').doc('bbb').update({
        data: {
          amount: _.inc(10)
        }
      })

      await transaction.commit()

      console.log(`transaction succeeded`)

      return {
        success: true,
        aaaAccount: aaaRes.data.amount - 10,
      }
    } else {
      await transaction.rollback()

      return {
        success: false,
        error: `rollback`,
        rollbackCode: -100,
      }
    }
  } catch (e) {
    console.error(`transaction error`, e)

    return {
      success: false,
      error: e
    }
  }
}


回答关注问题邀请回答
收藏

1 个回答

  • 哄哄
    哄哄
    2020-07-08

    你好,事务操作commit后才会整体执行,可以自己尝试一下去理解


    2020-07-08
    有用
    回复 15
    • 呼必斯哈拉图
      呼必斯哈拉图
      2020-07-08
      谢谢!那就是说只要不commit,就不会进入数据库呗。那么例子中的await transaction.rollback() 这部分在判断if (aaaRes.data && bbbRes.data) 为假的时候执行。这个时候为什么要rollback, 这部分还没进行任何更新操作。
      2020-07-08
      回复
    • 哄哄
      哄哄
      2020-07-08回复呼必斯哈拉图
      上边已经start了,所以需要返回原点。
      2020-07-08
      回复
    • 呼必斯哈拉图
      呼必斯哈拉图
      2020-07-08回复哄哄
      返回原点我能理解。那么如果const updateBBBRes = await transaction.collection('account').doc('bbb').update({
              data: {
                amount: _.inc(10)
              }
            })我写错了,或者因为某种原因发生异常的时候被catch 住了,那么这个时候怎么返回原点?因为这个时候不走else,而是走catch里边了吧,难道catch 会自动rollback?
      2020-07-08
      回复
    • 呼必斯哈拉图
      呼必斯哈拉图
      2020-07-08回复哄哄
      另外,如果我没写const db = cloud.database({
        throwOnNotFound: false,
      })的话是不是就没办法根据if (aaaRes.data && bbbRes.data)为假进行rollback返回原点了,对吗?我需要对每条更新(删除,添加)操作的结果进行判断来确定是不是需要进行rollback?多谢!
      2020-07-08
      回复
    • 哄哄
      哄哄
      2020-07-08回复呼必斯哈拉图
      事务过程中如果出现错误,会立刻终止事务并触发catch,没有try的话就直接函数报错
      2020-07-08
      1
      回复
    查看更多(10)
登录 后发表内容
问题标签