MongoDB Node.js应用使用客户端会话时出现‘Use of expired sessions is not permitted’错误
解决MongoDB会话过期错误:"Use of expired sessions is not permitted"
你这是踩了异步操作和会话生命周期配合的典型坑!这个错误的核心原因很明确:你在依赖会话的异步操作还没完成时,就提前调用了session.endSession()。
拆解下你的代码逻辑就懂了:insert()和count()都是异步的Promise操作,当你调用session.endSession()的时候,这两个操作可能还在后台跑着呢,等它们真正去使用会话时,会话已经被标记为过期,自然就抛出了错误。
修正方案1:在Promise链末尾结束会话
把session.endSession()放在Promise的then和catch块里,确保所有异步操作完成后再关闭会话:
const session = client.startSession(); const col = client.db('test').collection('test'); col .insert({a: true}, {w: 0, j: false, session}) .then(() => { return col.count({session}); }) .then(ret => { console.log(ret); session.endSession(); // 所有操作完成后再结束会话 }) .catch(err => { console.error(err); session.endSession(); // 即使出错也要关闭会话,避免资源泄漏 });
修正方案2:用async/await让逻辑更清晰
如果你的Node.js版本支持async/await(MongoDB 3.0客户端对应的Node.js版本完全没问题),这种写法会更直观,也更容易维护:
async function runDatabaseOperations() { const session = client.startSession(); try { const col = client.db('test').collection('test'); // 等待插入操作完成 await col.insert({a: true}, {w: 0, j: false, session}); // 等待计数操作完成 const ret = await col.count({session}); console.log(ret); } catch (err) { console.error(err); } finally { // 无论成功还是失败,都确保会话被关闭 session.endSession(); } } // 执行函数 runDatabaseOperations();
关键注意事项
- 会话一旦被
endSession()关闭,就无法再被任何数据库操作使用,必须严格保证所有依赖该会话的异步操作都在会话关闭前完成。 - 一定要在错误分支也处理会话关闭,否则可能会导致会话资源泄漏,影响后续的数据库操作。
内容的提问来源于stack exchange,提问作者Joey Yi Zhao
相关产品推荐
相关产品推荐

