问题描述
架构定义 用户集合:(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 → 当前日期
导致问题的场景:
- 在 12:01:01:100 毫秒 /cancel-booking/:bookingId - 发起了 PUT 调用并开始了猫鼬会话。
const session = await mongoose.startSession();
session.startTransaction();
const booking = await this.bookingsRepository.getBookingWithSession({ _id: bookingId },session)
user.pingedAt = new Date();
await user.save();
- 到 12:01:01:300 毫秒,通过 session 检索到的预订更改为 CANCELLED
booking.status = 3
await booking.save({ session })
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 (将#修改为@)