sequelize 操作表时如何给表加锁保证一致性?

聊天程序,用户可以抢马甲,如果两个用户同时抢,两个用户都会抢到这个马甲,如何让第一个用户操作表时阻塞这个表?

像下面这样的逻辑我该如何使用事务呢?

  rob_vest: async function (data, socket) {
        let vest_time = Date.now()
        console.log('时间错', vest_time)
        let sequlize = await db
        let phone = data.phone
        let room = data.room
        let url = data.url
        //查询马甲是否有人在使用
        let vest = await sequlize.models.user_vest.findOne({ where: { url: data.url, have_vest: 1, online: 1, room: room }, raw: true })
        let cool_vest = await sequlize.models.used_vest.findOne({ where: { phone, room, url }, raw: true })
        if (vest) {
            io.sockets.connected[socket.id].emit('rob_vest', { success: false, message: 'not avilable vest' })
            return
        }
        //判断是否在冷却时间
        if (!cool_vest) {
            console.log('*userd_time', vest_time)
            let used_time = vest_time
            console.log('userddddddddtime------------------', used_time)
            let data = await sequlize.models.used_vest.create({ phone, room, url, used_time })
        } else {
            let begin_time = cool_vest.used_time + 60 * 60 * 2 * 1000
            let stop_time = begin_time + 60 * 60 * 2 * 1000
            console.log(begin_time, vest_time, stop_time, '8989898989898', vest_time < stop_time && begin_time < vest_time)
            if (begin_time < vest_time && vest_time < stop_time) {
                io.sockets.connected[socket.id].emit('rob_vest', { success: false, msg: "马甲在冷却时间内不可以抢夺" })
                return
            } else {

                let used_time = vest_time
                sequlize.models.used_vest.update({ used_time }, { where: { phone, room, url } })
            }
        }
        //更新用户信息
        let update_user = await sequlize.models.chat_user.update({ have_vest: 1, url: data.url, vest_name: data.vest_name, vest_time: vest_time, room: room }, { where: { phone }, raw: true })
        // let update_vest = sequlize.models.chat_vest.update({ is_used: 1, used_time: vest_time }, { where: { url: data.url }, raw: true })
        if (update_user) {
            //抢马甲成功向房间内所有人广播
            io.to(room).emit('rob_vest', { success: true, phone: phone })
            schedules.addListenVest(io)
        } else {
            //抢马甲失败,向用户自己广播失败
            io.sockets.connected[socket.id].emit('rob_vest', { success: false, phone: phone })

        }
        }
阅读 6.9k
1 个回答

数据库里面用事务和锁来防止重复就行

其他的方法也可以,比如设置一个请求队列,先进先出,这样就可以按照顺序发马甲了

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题