Node.js MongoError:写入冲突

Node.js MongoError:写入冲突,node.js,mongodb,mongoose,concurrency,conflict,Node.js,Mongodb,Mongoose,Concurrency,Conflict,模式定义 用户集合:(optimisticConcurrency:true) 预订收藏(没有对该收藏施加优化一致性y) 所有对后端的api调用都有一个authenticate()中间件要交叉,该中间件在验证auth头中的令牌后通过查询用户进行身份验证。然后检索用户对象并最终更新以下属性 pingdat→ 当前日期 { _id: [Object Id], pingedAt: [Date], currentBal: [Int32], { ...otherUserAttibutes }

模式定义 用户集合:(optimisticConcurrency:true

预订收藏(没有对该收藏施加优化一致性y)

所有对后端的api调用都有一个authenticate()中间件要交叉,该中间件在验证auth头中的令牌后通过查询用户进行身份验证。然后检索用户对象并最终更新以下属性

pingdat→ 当前日期

{
  _id: [Object Id],
  pingedAt: [Date],
  currentBal: [Int32],
  { ...otherUserAttibutes }
}
导致问题的场景:

  • 12:01:01:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
  • 12:01:01:200ms用户进行/预订-接听电话,12:01:01:250ms在身份验证期间更新用户的pingedAt
  • 到12:01:01:300ms,通过会话检索到的预订更改为取消
  • 在同一个取消预订电话中,我们将钱添加到用户的钱包中。假设预订费是300/-。在12:01:01:350ms,我们将用户对象与更新的余额一起保存
  • WriteConflict引发错误,因为同一用户对象已在12:01:01发生更改:250ms

    错误日志

    MongoError: WriteConflict
      at MessageStream.messageHandler (/home/ubuntu/api.backend.js/node_modules/mongodb/lib/cmap/connection.js:268:20)
      at MessageStream.emit (events.js:315:20)
      at MessageStream.EventEmitter.emit (domain.js:483:12)
      at processIncomingData (/home/ubuntu/api.backend.js/node_modules/mongodb/lib/cmap/message_stream.js:144:12)
      MessageStream._write (/home/ubuntu/api.backend.js/node_modules/mongodb/lib/cmap/message_stream.js:42:5)
      at doWrite (_stream_writable.js:403:12)
      writeOrBuffer (_stream_writable.js:387:5)
      at MessageStream.Writable.write (_stream_writable.js:318:11)
      at TLSSocket.ondata (_stream_readable.js:716:22)
      at TLSSocket.emit (events.js:315:20)
      at TLSSocket.EventEmitter.emit (domain.js:483:12)
      at addChunk (_stream_readable.js:295:12)
      at readableAddChunk (_stream_readable.js:271:9)
      at TLSSocket.Readable.push (_stream_readable.js:212:10)
      at TLSWrap.onStreamRead (internal/stream_base_commons.js:186:23)
      at TLSWrap.callbackTrampoline (internal/async_hooks.js:120:14)}
    
        const session = await mongoose.startSession();
        session.startTransaction();
        const booking = await this.bookingsRepository.getBookingWithSession({ _id: bookingId }, session)
    
        user.pingedAt = new Date();
        await user.save();
    
        booking.status = 3
        await booking.save({ session })
    
        booking.user.currentBal = booking.user.currentBal + 300
        await booking.user.save({ session });
    
    MongoError: WriteConflict
      at MessageStream.messageHandler (/home/ubuntu/api.backend.js/node_modules/mongodb/lib/cmap/connection.js:268:20)
      at MessageStream.emit (events.js:315:20)
      at MessageStream.EventEmitter.emit (domain.js:483:12)
      at processIncomingData (/home/ubuntu/api.backend.js/node_modules/mongodb/lib/cmap/message_stream.js:144:12)
      MessageStream._write (/home/ubuntu/api.backend.js/node_modules/mongodb/lib/cmap/message_stream.js:42:5)
      at doWrite (_stream_writable.js:403:12)
      writeOrBuffer (_stream_writable.js:387:5)
      at MessageStream.Writable.write (_stream_writable.js:318:11)
      at TLSSocket.ondata (_stream_readable.js:716:22)
      at TLSSocket.emit (events.js:315:20)
      at TLSSocket.EventEmitter.emit (domain.js:483:12)
      at addChunk (_stream_readable.js:295:12)
      at readableAddChunk (_stream_readable.js:271:9)
      at TLSSocket.Readable.push (_stream_readable.js:212:10)
      at TLSWrap.onStreamRead (internal/stream_base_commons.js:186:23)
      at TLSWrap.callbackTrampoline (internal/async_hooks.js:120:14)}