MongoError:此 MongoDB 部署不支持可重试写入。请将 retryWrites=false 添加到您的连接字符串

And*_*per 26 mongoose mongodb

"mongoose": "^5.7.1"在我的 Node.js 项目中使用。我正在制作一个涉及更新两个文档的 api。所以,我正在使用如下交易:

// Start the transaction
session = await mongoose.startSession()
session.startTransaction()

await Promise.all([
   <1st update operation>,
   <2nd update operation>
])

// Commit the transaction
session.commitTransaction()
Run Code Online (Sandbox Code Playgroud)

当我在本地环境中点击此 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) => {...})
Run Code Online (Sandbox Code Playgroud)

以上都没有解决问题。

下面是mongo --version命令的输出:

db version v4.0.13
git version: bda366f0b0e432ca143bc41da54d8732bd8d03c0
allocator: system
modules: none
build environment:
    distarch: x86_64
    target_arch: x86_64
Run Code Online (Sandbox Code Playgroud)

我已经调试并发现抛出此错误背后的实际错误是:

MongoError:事务号只允许在副本集成员或 mongos 上

请提出一些建议。

gas*_*sbi 16

正如接受的答案中所建议的那样,您需要将本地服务器作为副本集运行才能执行事务,而不是独立服务器。

但是,除了建议的解决方案之外,您可以轻松地将独立本地数据库转换为副本集,而无需使用任何第三方工具,按照MongoDB 文档中的说明进行操作,总结如下:

  1. 停止您的独立 mongod 实例,并使用replSet参数重新启动它。
mongod --port 27017 --dbpath /srv/mongodb/db0 --replSet rs0 --bind_ip localhost
Run Code Online (Sandbox Code Playgroud)
  1. 使用mongoshell连接到您的实例,并启动新的副本集。
rs.initiate()
Run Code Online (Sandbox Code Playgroud)

现在您应该拥有一个副本集而不是独立的 mongodb 服务器,您可以在其中在本地环境中执行事务以一次更新多个文档!

replSet每次要启动服务器时不要忘记包含该参数,否则它将作为独立启动。我只是使用与步骤 1 中相同的命令再次运行它。


或者,您可以按照MongoDB 文档中的其他说明从头开始部署新的副本集以测试环境


And*_*per 6

事务无疑是 MongoDB 4.0 中最令人兴奋的新功能。但不幸的是,大多数用于安装和运行 MongoDB 的工具都会启动独立服务器,而不是副本集。如果您尝试在独立服务器上启动会话,您将收到此错误。

可以通过在本地环境中使用副本集来解决此问题。

我为此目的使用了run-rs 。


kri*_*ris 6

请尝试添加&retryWrites=false到您的连接字符串

--

实际上,当我连接到远程数据库服务器时,我遇到了OP中提到的错误,而它是在本地工作的。在尝试错误中的建议之前,我联系了我们的 mongo 托管支持。

--

这是我们托管的 mongo 网站 (mLab) 所说的:

您的应用程序的驱动程序可能已更新到较新的版本,该版本正在尝试使用仅限 WiredTiger 的功能。正如错误所述,您需要将 &retryWrites=false 添加到连接字符串中。

https://docs.mlab.com/faq/#why-am-i-getting-the-transaction-numbers-are-only-allowed-on-storage-engines-that-support-document-level-locking-error

  • 这取决于您的连接字符串上是否已经有 URL 参数,如果有,则使用 &amp;,如果没有,则使用 ? (2认同)