Node.js连接MongoDB报MongoExpiredSessionError会话已结束问题问询
报错根因
- MongoDB Node.js 驱动4.x+版本中,
collection.insertOne()为异步方法,返回Promise对象,你的代码未添加await关键字等待操作执行完成,就提前调用client.close()关闭了数据库连接,导致插入操作绑定的会话被提前销毁,触发MongoExpiredSessionError。 - 你的
app.js中app.get('/products')未绑定对应的getProducts处理函数,会导致该接口无响应。
修复方案
1. 修复mongo.js代码
给insertOne添加await,同时将client.close()放到finally块中,保证出现异常时数据库连接也能正常关闭:
const MongoClient = require("mongodb").MongoClient; const url ='xxxxxx' const createProduct = async (req, res, next) => { const newProduct = { name: req.body.name, price: req.body.price }; const client = new MongoClient(url); try { await client.connect(); const db = client.db(); // 新增await等待插入完成 const result = await db.collection('products').insertOne(newProduct); } catch (error) { // 可自行添加错误日志打印方便排查 console.log(error) return res.json({message: 'Could not store data.'}); } finally { // 连接关闭逻辑放到finally块,保证异常时也能关连 client.close(); } res.json(newProduct); }; const getProducts = async (req, res, next) => { const client = new MongoClient(url); let products; try { await client.connect(); const db = client.db(); products = await db.collection('products').find().toArray(); } catch (error) { console.log(error) return res.json({message: 'Could not retrieve products.'}); } finally { client.close(); } res.json(products); }; exports.createProduct = createProduct; exports.getProducts = getProducts;
2. 修复app.js代码
给get路由绑定处理函数:
const express = require('express'); const bodyParser = require('body-parser') const mongoPractice =require('./mongo') const app = express(); app.use(bodyParser.json()); app.post('/products',mongoPractice.createProduct); // 绑定getProducts处理函数 app.get('/products', mongoPractice.getProducts); app.listen(3000);
性能优化建议
不推荐每次请求都新建MongoClient实例,MongoDB驱动内置了连接池,你可以全局初始化一次MongoClient复用连接,减少频繁建连断连的性能开销,代码示例如下:
// mongo.js 全局初始化连接 const MongoClient = require("mongodb").MongoClient; const url ='xxxxxx' // 全局复用client let client = new MongoClient(url); let dbInstance = null; // 初始化连接 const initDb = async () => { if (!dbInstance) { await client.connect(); dbInstance = client.db(); } return dbInstance; } const createProduct = async (req, res, next) => { const newProduct = { name: req.body.name, price: req.body.price }; try { const db = await initDb(); await db.collection('products').insertOne(newProduct); } catch (error) { console.log(error) return res.json({message: 'Could not store data.'}); } res.json(newProduct); }; // getProducts方法同理复用initDb获取db实例,不需要每次新建client
内容的提问来源于stack exchange,提问作者Milán Nikolics
相关产品推荐
相关产品推荐

