加了 --replSet 就能用事务,本质是启用 oplog、选举框架和事务编号分配器等副本集核心机制;单节点副本集支持完整事务功能但无容错能力;Windows 服务需在安装时显式传入该参数并执行 rs.initiate() 才生效。

为什么加了 --replSet 就能用事务?本质是启用了 oplog 和选举框架
加 --replSet rs0 不是“假装”有副本集,而是让单个 mongod 进程真正以副本集成员身份启动——它会创建并维护 local.oplog.rs 集合,启用心跳、选举状态机、事务编号(txnNumber)分配器等全套机制。事务提交时依赖的 oplog 写入、prepare/commit 日志持久化、回滚日志(local.rollback.1)等组件,全部被激活。没有这个参数,mongod 根本不初始化这些模块,所以报错 Transaction numbers are only allowed on a replica set member or mongos 是硬性校验,不是提示。
--replSet 单节点副本集和真实多节点副本集的区别在哪?
单节点副本集(如 mongod --replSet rs0)与三节点副本集在事务能力上完全一致,但缺少容错能力:
- 它能执行
session.startTransaction()、写入 oplog、支持commitTransaction()/abortTransaction() - 但它无法做故障转移:没有其他节点可投票,
rs.status()中只有自己一个PRIMARY,且状态永远是"health": 1, "stateStr": "PRIMARY" - oplog 是单点存储,宕机后未同步到磁盘的事务日志可能丢失(这点和单机模式一样,但比纯单机多了日志结构)
- 所有读写仍只落在本地,不涉及网络复制延迟,性能开销仅来自 oplog 维护本身
Windows 上用服务方式运行时,--replSet 必须写进配置或安装命令
如果 MongoDB 是作为 Windows 服务安装的(比如通过 mongod --install),光改 mongod.cfg 里的 replSetName: rs0 不够——服务注册时没带 --replSet 参数,启动时仍按单机模式加载。必须重新安装服务,并显式传入该参数:
mongod --dbpath "C:\data\rs0" --logpath "C:\data\mongo.log" --port 27017 --replSet rs0 --bind_ip localhost --install --serviceName "MongoDBRS"
否则即使配置文件写了,服务启动日志里也会出现 replication not enabled,rs.initiate() 会失败。
容易忽略的关键验证点:必须执行 rs.initiate() 才算真正就绪
启动带 --replSet 的 mongod 后,它只是“准备好当副本集成员”,但还没成为有效副本集。必须连上 mongosh(或旧版 mongo shell),执行:
rs.initiate({ _id: "rs0", members: [{ _id: 0, host: "localhost:27017" }] })
之后再运行 rs.status(),看到 "ok" : 1 和 "stateStr" : "PRIMARY",才算事务环境真正可用。跳过这步,应用连接后调 startSession() 会卡住或抛出 NotYetInitialized 错误。


















