小程序云开发 测试 事务使用

1、新建用户集合user,存储用户信息,里面包括了当前用户是第几位,发现小程序云数据库并没有类似mysql一样的自动增长字段(表示用户位数),需要自己实现。
小程序云开发 测试 事务使用
2、为了实现自动增长,需要新建一个集合counters
小程序云开发 测试 事务使用
手动插入一条记录,用于保存当前总共有几位用户,注意sequence_value字段的类型是数字
{
"_id":"productid",
"sequence_value": 0
}
小程序云开发 测试 事务使用
当有用户访问时,将counters集合下唯一记录的sequence_value字段加1,并作为当前用户位数添加到用户表。

exports.main = async (event, context) => {
const aaaRes = await db.collection('counters').doc('productid').get()
await db.collection('counters').doc('productid').update({
  // data 传入需要局部更新的数据
  data: {
    sequence_value: db.command.inc(1)
  }
})
let place = ++aaaRes.data.sequence_value //place代表第XX位用户
await db.collection('user').add({
// data 字段表示需新增的 JSON 数据
data: {
    _openid: cloud.getWXContext().OPENID,
    place,
    name: event.name,
    mobile: event.mobile,
    _createTime: Date.now(),
    }
})
}

自动增长字段就完成了,这时还需要考虑的就是不同的用户同时访问云函数时的冲突情况。
3、冲突指两个用户同时访问云函数时,获得的sequence_value值是一样的,添加到用户表的用户位数也相同,不够准确。这时,可以使用小程序的事务解决冲突。

const db = cloud.database()
const _ = db.command
// 云函数入口函数
exports.main = async (event, context) => {
  const wxContext = cloud.getWXContext()
  try {
    const result = await db.runTransaction(async transaction => {
      const aaaRes = await transaction.collection('counters').doc('productid').get()

      if (aaaRes.data) {
          
        await transaction.collection('counters').doc('productid').update({
          data: {
            sequence_value: _.inc(1)
          }
        })
        let place = ++aaaRes.data.sequence_value //place代表全国第XX位用户
    
        await transaction.collection('user').add({
          // data 字段表示需新增的 JSON 数据
          data: {
            _openid: wxContext.OPENID,
            place,
            name: event.name,
            mobile: event.mobile,
          }
        })
    

        console.log(`transaction succeeded`)

        // 会作为 runTransaction resolve 的结果返回
        return {
          place,
        }
      } else {
        // 会作为 runTransaction reject 的结果出去
        await transaction.rollback(-100)
      }
    })

    return {
      success: true,
      place: result.place,
    }
  } catch (e) {
    console.error(`transaction error`, e)

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

因为事务期间的写操作会让对象加上事务锁,使两个并发的事务中的一个写入失败,直至事务提交。保证了写入用户表的记录用户位数唯一。

上一篇:allegro-2020-11-25


下一篇:十大排序算法的分析