MongoError:写入冲突

问题描述

架构定义 用户集合:(optimisticConcurrency: true)

{
  _id: [Object Id],pingedAt: [Date],currentBal: [Int32],{ ...otherUserAttibutes }
}

预订集合(没有乐观并发y强加给这个集合)

{
  _id: [Object Id],user: [Ref to User -> the user for whom the booking was made],status: [0,1,2,3,...]
  { ...otherBookingAttributes }
}

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

pingedAt → 当前日期

导致问题的场景:

  1. 在 12:01:01:100 毫秒 /cancel-booking/:bookingId - 发起了 PUT 调用并开始了猫鼬会话。
    const session = await mongoose.startSession();
    session.startTransaction();
    const booking = await this.bookingsRepository.getBookingWithSession({ _id: bookingId },session)
  1. 在 12:01:01:200 毫秒,用户发出 /bookings - GET 调用,并在 12:01:01:250 毫秒,用户的 pingedAt 在身份验证期间更新.
    user.pingedAt = new Date();
    await user.save();
  1. 到 12:01:01:300 毫秒,通过 session 检索到的预订更改为 CANCELLED
    booking.status = 3
    await booking.save({ session })
  1. 在同一个取消预订电话中,我们向用户的钱包充值。说预订费是300/-。在 12:01:01:350 毫秒,我们保存更新余额的用户对象。
    booking.user.currentBal = booking.user.currentBal + 300
    await booking.user.save({ session });

WriteConflict 错误被抛出,因为同一个用户对象已经在 12:01:01:250 ms

错误日志

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)}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...