Next.js+Mongoose连接DataStax Astra遇findOne()超时问题求助
问题:Next.js中使用DataStax Astra + Mongoose时
emails.findOne()缓冲超时 我在Next.js项目里开发通讯邮件应用,用DataStax Astra作为数据库,已经写好数据存储逻辑,但一直碰到emails.findOne()缓冲超时(10000ms)的问题,试了各种方法都解决不了。
数据库连接代码(db.ts)
import mongoose from "mongoose"; import { driver, createAstraUri } from "stargate-mongoose"; export const connectDb = async () => { try { const uri = createAstraUri( process.env.ASTRA_DB_API_ENDPOINT!, process.env.ASTRA_DB_APPLICATION_TOKEN! ); if (mongoose.connection.readyState !== 0) { await mongoose.disconnect(); } mongoose.set("autoCreate", true); mongoose.setDriver(driver); await mongoose .connect(uri, { isAstra: true }) .then((res) => { console.log("Connected"); }) .catch((r) => { console.log(r); }); } catch (error) { console.log(error); } };
邮件保存逻辑(Save_Email.ts)
"use server"; import Email from "@/models/email.model"; import { connectDb } from "@/shared/libs/db"; export const saveEmail = async ({ title, content, newsLetterOwnerId, }: { title: string; content: string; newsLetterOwnerId: string; }) => { try { await connectDb(); const email = await Email.findOne({ title, newsLetterOwnerId, }); if (email) { await Email.findByIdAndUpdate(email._id, { content, }); return { message: "Email updated successfully!" }; } else { await Email.create({ title, content, newsLetterOwnerId, }); return { message: "Email saved successfully!" }; } } catch (error) { console.log(error); } };
邮件Schema代码
import mongoose from "mongoose"; const { Schema } = mongoose; const emailSchema = new Schema( { title: { type: String, }, content: { type: String, }, newsLetterOwnerId: { type: String, }, }, { timestamps: true } ); const Email = mongoose.models.Email || mongoose.model("Email", emailSchema); export default Email;
报错信息
Connected MongooseError: Operation `emails.findOne()` buffering timed out after 10000ms at Timeout.<anonymous> (D:\Projects\Portfolio\Newsletter\node_modules\mongoose\lib\drivers\node-mongodb-native\collection.js:185:23) at listOnTimeout (node:internal/timers:569:17) at process.processTimers (node:internal/timers:512:7)
解决方案
1. 修复数据库连接逻辑
你的connectDb函数每次调用都会强制断开现有连接再重连,这会导致连接状态不稳定,数据库操作发起时连接还未就绪,最终触发超时。改成仅在未连接时建立连接:
修改db.ts:
import mongoose from "mongoose"; import { driver, createAstraUri } from "stargate-mongoose"; export const connectDb = async () => { try { // 已连接则直接返回,避免重复连接 if (mongoose.connection.readyState === 1) { return; } const uri = createAstraUri( process.env.ASTRA_DB_API_ENDPOINT!, process.env.ASTRA_DB_APPLICATION_TOKEN! ); mongoose.set("autoCreate", true); mongoose.setDriver(driver); await mongoose.connect(uri, { isAstra: true }); console.log("Connected to Astra DB"); } catch (error) { console.error("DB连接失败:", error); throw error; // 抛出错误让上层处理,避免静默失败 } };
2. 验证Astra配置正确性
- 确认
ASTRA_DB_API_ENDPOINT是正确的集群API端点(格式如https://<cluster-id>.apps.astra.datastax.com) - 检查
ASTRA_DB_APPLICATION_TOKEN是否拥有读写权限,且未过期 - 确保Astra控制台中已创建对应的命名空间(若需手动创建)
3. 调整缓冲超时时间(可选)
如果网络连接较慢,可延长Mongoose的缓冲超时时间:
await mongoose.connect(uri, { isAstra: true, bufferTimeoutMS: 30000 // 延长至30秒 });
4. 确认集合创建
Mongoose的autoCreate应自动创建集合,若未生效,可手动在Astra控制台创建emails集合(注意是复数,Mongoose会自动将模型名转为复数形式)。
5. 操作前确认连接状态
修改saveEmail函数,确保连接成功后再执行数据库操作:
"use server"; import mongoose from "mongoose"; import Email from "@/models/email.model"; import { connectDb } from "@/shared/libs/db"; export const saveEmail = async ({ title, content, newsLetterOwnerId, }: { title: string; content: string; newsLetterOwnerId: string; }) => { try { await connectDb(); // 确认连接状态正常 if (mongoose.connection.readyState !== 1) { throw new Error("数据库未连接"); } const email = await Email.findOne({ title, newsLetterOwnerId, }); if (email) { await Email.findByIdAndUpdate(email._id, { content }); return { message: "邮件更新成功!" }; } else { await Email.create({ title, content, newsLetterOwnerId }); return { message: "邮件保存成功!" }; } } catch (error) { console.error("保存邮件失败:", error); return { error: "操作失败,请稍后重试" }; } };
内容的提问来源于stack exchange,提问作者Shadow Gaming
相关产品推荐
相关产品推荐

