我正在嘗試與貓鼬進行交易。
當我運行代碼時,看起來 mongoose 檔案即使在呼叫await session.endSession(). 后來,當我在該檔案上呼叫 .save() 時,我收到錯誤“不允許使用過期會話”。
這是演示(只是一個簡化的例子):
const MessageSchema = new mongoose.Schema({ text: String }, {strict: 'throw'});
const Message = mongoose.model('Message', MessageSchema);
const session = await mongoose.startSession();
let message;
await session.withTransaction(async () => {
message = (await Message.create([{text: 'My message'}], {session}))[0];
});
await session.endSession();
message.text = 'My message 2';
await message.save();
決賽.save()拋出了那個錯誤。如果你會記錄message.$session().hasEnded你會得到真實的。我的期望是,如果會話結束, .save() 不使用它會很聰明。
我想要實作的目標:創建一些帶有事務的檔案,提交它們,這樣它們就在資料庫中。
稍后,使用已在資料庫中的相同檔案對其進行一些更改。
我在這里做錯了什么?如何防止.save()拋出錯誤并嘗試使用過期會話?
uj5u.com熱心網友回復:
mongoose 檔案中的endSession任何地方都沒有任何部分,但是正如您自己很好地發現的那樣,當呼叫此函式時,它只會為您的物件設定一個標志而不是銷毀它。如果它被破壞了,你將有另一個錯誤。session
我的期望是,如果會話結束, .save() 不使用它會很聰明。
事實上,它足夠聰明,不使用它,該框架只會通知您您正在嘗試非法指令。
我想要實作的目標:創建一些帶有事務的檔案,提交它們,這樣它們就在資料庫中。
這正是你對你的withTransaction電話所做的。這個包裝器可以幫助您創建、提交和中止/重試,以防發生不好的事情,所以在呼叫之后并且如果一切順利,您確實成功地在資料庫中創建了一個檔案。
稍后,使用已在資料庫中的相同檔案對其進行一些更改。
取決于您所說的“以后”是什么意思。如果它是同一個端點的一部分(我不知道為什么你會立即修改該檔案而不是首先正確地提交它),那么正如我在評論中所說,移動endSession呼叫可能會解決問題:
const MessageSchema = new mongoose.Schema({ text: String }, {strict: 'throw'});
const Message = mongoose.model('Message', MessageSchema);
const session = await mongoose.startSession();
let message;
await session.withTransaction(async () => {
message = (await Message.create([{text: 'My message'}], {session}))[0];
});
message.text = 'My message 2';
await message.save();
await session.endSession();
如果它是另一個端點的一部分,那么只需像剛才一樣進行另一個事務,除非您修改檔案而不是創建它。或者,如果您根本不需要事務,請使用類似findOneAndUpdateor的方法findByIdAndUpdate。我認為您似乎對 JS 和 Mongoose 足夠熟悉,可以自行完成。
我在這里做錯了什么?
基本上,不多。您已經明白,.save()在結束會話后您不能打電話。
如何防止
.save()拋出錯誤并嘗試使用過期會話?
你不能。這只是提醒您正在嘗試非法操作。但是,您可以嘗試/捕獲錯誤并決定在您的catch子句中對此不做任何事情,或者撰寫一個 if 陳述句檢查message.$session().hasEnded.
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/405567.html
標籤:
上一篇:使用貓鼬時無法獲取
下一篇:如何優化mongodb聚合查詢
