我在 Node.js 项目中使用
"mongoose": "^5.7.1"
。我正在制作一个 api,其中涉及更新两个文档。所以,我正在使用如下交易:
// Start the transaction
session = await mongoose.startSession()
session.startTransaction()
await Promise.all([
<1st update operation>,
<2nd update operation>
])
// Commit the transaction
session.commitTransaction()
当我在本地环境中使用此 api 时,出现以下错误:
MongoError:此 MongoDB 部署不支持可重试写入。请将 retryWrites=false 添加到您的连接字符串中。
当我在远程环境中使用这个 api 时,它运行良好。我使用 https://www.clever-cloud.com 作为数据库云,使用 AWS 作为 API 云。
如错误消息中所写,我尝试将
retryWrites=false
mongodb://${ip}:${port}/${this.MONGO_DATABASE}?retryWrites=false
retryWrites: false
传递给 mongoose.connect
方法。mongoose.connect(`mongodb://${ip}:${port}/${this.MONGO_DATABASE}`, {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
retryWrites: false
}, (err) => {...})
以上均未解决问题。
以下是
mongo --version
命令的输出:
db version v4.0.13
git version: bda366f0b0e432ca143bc41da54d8732bd8d03c0
allocator: system
modules: none
build environment:
distarch: x86_64
target_arch: x86_64
我进行了调试,发现引发此错误的实际错误是:
MongoError:事务编号仅允许在副本集成员或 mongos 上
请提出建议。
正如已接受的答案中所建议的,您需要将本地服务器作为副本集运行才能执行事务,而不是独立服务器。
但是,除了建议的解决方案之外,您还可以轻松地将独立本地数据库转换为副本集,无需使用任何第三方工具,按照 MongoDB 文档中的说明进行操作,总结如下:
replSet
参数重新启动它。mongod --port 27017 --dbpath /srv/mongodb/db0 --replSet rs0 --bind_ip localhost
mongo
shell 连接到您的实例,并启动新的副本集。rs.initiate()
现在您应该拥有一个副本集而不是独立的 mongodb 服务器,您可以在本地环境上执行事务以一次更新多个文档!
不要忘记每次要启动服务器时都包含
replSet
参数,否则它将作为独立启动。我只是使用与步骤 1 中相同的命令再次运行它。
或者,您可以按照 MongoDB 文档中的其他说明从头开始部署新的副本集用于测试环境。
事务无疑是 MongoDB 4.0 中最令人兴奋的新功能。但不幸的是,大多数用于安装和运行 MongoDB 的工具都会启动独立服务器,而不是副本集。如果您尝试在独立服务器上启动会话,您将收到此错误。
这个问题可以通过在本地环境中使用replica-sets来解决。
为此目的,我使用了 run-rs。
请尝试将
&retryWrites=false
添加到您的连接字符串中。
我实际上在连接到远程数据库服务器时遇到了OP中提到的错误,而它在本地工作。 在尝试错误中的建议之前,我联系了我们的 mongo 托管支持。
这是我们托管的 mongo 网站(mLab)所说的:
您的应用程序的驱动程序可能已更新到较新的版本,该版本正在尝试使用仅限 WiredTiger 的功能。正如错误所述,您需要将 &retryWrites=false 添加到连接字符串中。
请编辑
App/Config/database
文件在Mongodb连接字符串中添加'retryWrites'=>false
写入 Mongo 数据库连接
'mongodb' => [
'driver' => 'mongodb',
'host' => env('MONGO_DB_HOST', 'lo*****'),
'port' => *****,
'database' => env('MONGO_DB_DATABASE'),
'username' => env('MONGO_DB_USERNAME'),
'password' => env('MONGO_DB_PASSWORD'),
'options' => [
'database'=> env('MONGO_DB_DATABASE'),
'retryWrites'=>false
]
],
保存并运行