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

Posted

技术标签:

【中文标题】MongoError:此 MongoDB 部署不支持可重试写入。请将 retryWrites=false 添加到您的连接字符串【英文标题】:MongoError: This MongoDB deployment does not support retryable writes. Please add retryWrites=false to your connection string 【发布时间】:2020-02-23 15:25:26 【问题描述】:

我在我的 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 时,出现以下错误:

中。

当我在远程环境中点击这个 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 上使用

请提出一些建议。

【问题讨论】:

我也开始看到这些错误。我在 Heroku 上使用 Mlab。但是在客户端上添加选项解决了这个问题。我刚刚尝试了 URI 版本,它也可以正常工作。奇怪。 我使用的是独立服务器,这导致了这个错误。最初的错误不是实际的,后面的错误可以通过副本集或共享集群来解决。见npmjs.com/package/run-rs 【参考方案1】:

在 Ubuntu 上,您需要使用

sudo mongod --port 27017 --dbpath /var/lib/mongodb --replSet rs1 --bind_ip localhost

因为数据库一般安装在/var/lib/mongodb上。

发布这个,输入一个 mongo shell,然后调用 rs.initiate()。在终端中,

mongo
rs.initiate()

【讨论】:

我建议将此作为对投票最多的答案的评论,因为它为相同的提议解决方案添加了其他信息。它可能会在那里获得更多的知名度,Ubuntu 上的人可能会喜欢它。【参考方案2】:

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

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

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

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

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


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

【讨论】:

【参考方案3】:

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

--

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

--

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

您的应用驱动程序很可能已更新至尝试使用 WiredTiger-only 功能的较新版本。正如错误所述,您需要将 &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

【讨论】:

你应该添加到字符串连接 ?retryWrites=false 而不是 &retryWrites=false 这取决于你的连接字符串上是否已经有 URL 参数,如果有使用 &,如果没有使用?【参考方案4】:

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

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

我为此使用了run-rs。

【讨论】:

【参考方案5】:

请编辑App/Config/database文件在Mongodb连接字符串中添加'retryWrites'=&gt;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
            ]
        ],

保存并运行

【讨论】:

我找不到这个文件 @TayyabFerozi 您必须将此文件创建为数据库配置文件,在您的 nodejs 项目中通过此文件在环境变量中定义数据库常量。

以上是关于MongoError:此 MongoDB 部署不支持可重试写入。请将 retryWrites=false 添加到您的连接字符串的主要内容,如果未能解决你的问题,请参考以下文章

MongoError:套接字挂起

MongoError:套接字挂起

MongoDB 通过 Mlab - MongoError:身份验证失败

MongoError:身份验证失败。 NestJs MongoDb 图集

未处理的拒绝 MongoError:无法连接到 MongoDB 中的服务器

MongoError:在 mongoDB atlas 中首次连接时无法连接服务