该错误表明MongoDB单机模式不支持事务,因事务强依赖副本集的oplog机制;需启动时加--replSet参数并执行rs.initiate()初始化单成员副本集,且host必须为localhost。

“Transaction numbers are only allowed on a replica set member or mongos” 这个错误不是配置漏了、驱动写错了,而是 MongoDB 服务端直接拒绝执行事务——单机模式(standalone)压根不支持事务,连协议层都关掉了。
为什么本地 mongod 启动就报 Transaction numbers 错误
这个错误出现的唯一原因:你正在用 mongod 默认方式启动,没声明自己是副本集成员。MongoDB 4.0+ 的事务强依赖 oplog 和副本集协调机制,单机模式不生成 oplog、无主从角色、无投票能力,服务端在收到 startTransaction 命令时立刻返回该错误。
验证很简单:db.runCommand({ replSetGetStatus: 1 }) 在单机上必然返回 no replset config has been received —— 这比查版本号还准。
注意:--enableMajorityReadConcern、storage.journal.enabled: true 这类参数对解决此错误完全无效,它们影响的是读关注或持久化,不是事务准入资格。
用 rs.initiate() 把单机变成事务可用副本集
不需要多台机器、不用改应用连接地址(仍连 localhost:27017),只要让这个 mongod “声明身份”即可。核心就两步:启动带 --replSet 参数 + 连上去执行 rs.initiate()。
- 停掉当前运行的
mongod(避免端口冲突) - 新建空数据目录,例如
/data/rs0(Windows 下可用C:\data\rs0),确保有读写权限 - 用以下命令启动:
mongod --replSet rs0 --dbpath /data/rs0 --port 27017 --bind_ip localhost - 用
mongo --host localhost:27017连入,执行:rs.initiate({ _id: "rs0", members: [{ _id: 0, host: "localhost:27017" }] })(必须用localhost,不能用127.0.0.1,否则驱动解析失败会导致 session 创建被拒) - 等
rs.status().stateStr返回"PRIMARY"就可用了
事务能 start 了,但 commit 失败?检查 readConcern 和 writeConcern
副本集有了,不代表事务就能 commit 成功。MongoDB 强制要求事务内所有操作显式指定兼容级别,否则会静默降级或直接报错。
- 读操作必须设
readConcern: "majority"(4.2+ 推荐)或"snapshot"(4.0+);"local"不被允许 - 写操作必须设
writeConcern: { w: "majority" };设成{ w: 1 }会触发错误Transaction numbers require a majority - Node.js 驱动示例:
session.startTransaction({ readConcern: { level: "majority" }, writeConcern: { w: "majority" } })
最容易被忽略的细节:host 必须是 localhost
rs.initiate() 里写的 host 字段,哪怕你只有一台机器,也必须填 "localhost",不能填 "127.0.0.1" 或域名。MongoDB 驱动会尝试反向解析主机名,如果解析失败或不匹配,后续创建事务 session 时会被服务端拒绝,错误表现仍是 Transaction numbers are only allowed... —— 看似一样,但原因已不同。

















