Mongodb v4.0事务,MongoError:只允许在副本集成员或mongos上使用事务编号

jaf*_*adi 15 javascript transactions mongodb node.js

我已经安装MongoDB v4.0了它最神奇的功能,交易中使用的NodeJS mongodb3.1的驱动程序.

当我尝试使用事务会话时,我遇到了这个错误:

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

那是什么,怎么能摆脱它?

任何建议表示赞赏.

Ore*_*ili 34

我得到了解决方案,它只是 MongoDB 配置文件中的三行配置。

从 MongoDB atlas 切换并使用 WHM 在我的 CentOS 7 VPS 上安装 MongoDB v 4.4.0 后,我也遇到了这个问题。

run-rs解决方案对我不起作用,但我设法在没有任何第三方工具的情况下解决了这个问题,按照以下步骤操作:

1. 关闭mongod

最有效的方法是使用命令mongo checkout 进入 MongoDB shell 方法

db.shutdownServer()
Run Code Online (Sandbox Code Playgroud)

您将无法使用 MongoDB 服务器。对我来说,关闭过程花了太长时间,然后我用命令杀死了该进程:

systemctl stop -f mongod
Run Code Online (Sandbox Code Playgroud)

如果你杀死了这个mongod进程,你可能需要运行 mongod --dbpath /var/db --repair

var/db指向您的数据库目录。

2. 设置replicaSet配置。

对于replicaSet设置步骤,检查/etc/mongod.conf文件,查找replication值行,并且您应该添加以下行,如下所示:

replication:
   oplogSizeMB: <int>
   replSetName: <string>
   enableMajorityReadConcern: <boolean>
Run Code Online (Sandbox Code Playgroud)

replSetName在下一步中使用该值。

这些设置的示例:

   oplogSizeMB: 2000
   replSetName: rs0
   enableMajorityReadConcern: false
Run Code Online (Sandbox Code Playgroud)

3. 添加您的连接字符串 URL。

将 replSetName 的值添加到您的连接 URL&replicaSet=--YourReplicationSetName--

如果您使用了我们示例中的名称rs0,那么您应该添加到您的数据库连接 URL 查询replicaSet=rs0

4.再次开启mongod

输入命令:systemctl start mongod

5. 访问您的replicaSet数据库

使用命令进入 MongoDB shell mongo,现在输入命令rs.initiate() 您应该位于副本集数据库中。

  • 我认为本地发展的最佳解决方案。这真的很容易做到并且无需任何第三方软件即可工作。 (2认同)

Kir*_*ill 17

docker-compose.yaml对于那些想要针对 dockerized MongoDB 实例进行开发的人,这里是基于官方 MongoDB docker 映像的单文件解决方案:

version: '3.8'

services:
  mongodb:
    image: mongo:5
    command: --replSet rs0
    ports:
      - "28017:27017"
    environment:
      MONGO_INITDB_DATABASE: attachment-api-local-dev
    healthcheck:
      # use 'mongo' instead of 'mongosh' if MongoDB version is lower than 5
      test: mongosh --eval 'db.runCommand("ping").ok' localhost:27017/test --quiet
      interval: 2s
      timeout: 3s
      retries: 5

  mongo-init:
    image: mongo:5
    restart: "no"
    depends_on:
      mongodb:
        condition: service_healthy
    command: >
      mongo --host mongodb:27017 --eval
      '
      rs.initiate( {
         _id : "rs0",
         members: [
            { _id: 0, host: "localhost:27017" }
         ]
      })
      '
Run Code Online (Sandbox Code Playgroud)

一个更简单的解决方案是仅使用Bitnami MongoDB 图像

services:
  mongodb:
    image: bitnami/mongodb:5.0
    ports:
      - "27017:27017"
    environment:
      MONGODB_REPLICA_SET_MODE: primary
      ALLOW_EMPTY_PASSWORD: 'yes'
Run Code Online (Sandbox Code Playgroud)


Maj*_*vin 13

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

为了使用事务,您需要一个MongoDB副本集,并且在本地启动副本集进行开发是一个复杂的过程。新版本run-rs npm module使启动副本集变得容易。运行run-rs是启动副本集所需的全部,run-rs甚至会为您安装正确版本的MongoDB。

Run-rs除Node.js和npm外没有其他依赖项。您无需安装Docker,自制软件,APT,Python甚至MongoDB。

使用npm's -gflag 在全局安装run-rs 。您还可以在package.json文件的devDependencies中列出运行器。

npm install run-rs -g
Run Code Online (Sandbox Code Playgroud)

接下来,使用--version标志运行run-rs。Run-rs将为您下载MongoDB v4.0.0。不用担心,它不会覆盖您现有的MongoDB安装。

run-rs -v 4.0.0 --shell
Run Code Online (Sandbox Code Playgroud)

然后replicaSet=rs在您的连接字符串中使用。

您可以在此处找到有关它的更多详细信息。

  • 知道为什么使用事务的能力需要 MongoDB 副本集吗?(在我的例子中,我有在 docker 上运行的 MongoDb 实例进行测试,并且由于遵循此限制而无法运行事务) (11认同)
  • 为什么需要副本集?这对我来说毫无意义,似乎这是 mongodb 团队的一个错误。 (6认同)
  • 从文档看来,运行具有副本集的现有(或新的)“ mongod”实例相当简单:https://docs.mongodb.com/manual/tutorial/convert-standalone-to-replica-set/ (2认同)
  • @MarcelFalliere 它看起来很微不足道,但它的设计方式使得在 Docker 中实现它会很痛苦。从另一个答案来看,他们似乎已经破坏了一个 Docker 解决方案。也许他们讨厌 Docker、讨厌事务或引诱我们使用副本?这毫无意义,并且违背了我们迄今为止制定的任何原则...... (2认同)

小智 13

使用docker进行本地开发的可能解决方案

创建 Dockerfile

FROM mongo:4.4.7
RUN echo "rs.initiate();" > /docker-entrypoint-initdb.d/replica-init.js
CMD [ "--replSet", "rs" ]
Run Code Online (Sandbox Code Playgroud)

构建这个 Dockerfile

docker build ./ -t mongodb:4.7-replset
Run Code Online (Sandbox Code Playgroud)

运行这个创建的图像

docker run --name mongodb-replset -p 27017:27017 -d mongodb:4.7-replset
Run Code Online (Sandbox Code Playgroud)

使用此 URI 连接到数据库

mongodb://localhost:27017/myDB
Run Code Online (Sandbox Code Playgroud)


Ric*_*cky 7

我最近遇到了同样的问题。就我而言,这是因为我要连接到与本地开发环境版本不同的远程 Mongo 服务器。

为了快速解决这个问题,我在我的连接字符串中添加了以下参数:

? 重试写入=假

  • 这看起来相当可疑。您确定它不会只是让所有错误保持沉默而不是修复它们吗?为什么它应该有效? (5认同)

Abd*_*rai 6

在 Linux 机器上运行 MongoDB 时,您可以通过编辑服务文件更新连接字符串来简单地使用复制

/usr/lib/mongod.service   or   /lib/systemd/system/mongod.service
Run Code Online (Sandbox Code Playgroud)

并用以下内容更新它

ExecStart=/usr/bin/mongod --config "/etc/mongod.conf" --replSet rs0
Run Code Online (Sandbox Code Playgroud)

其中--config "/etc/mongod.conf"指向您的 MongoDB 配置文件并--replSet rs0告诉它使用名称为的复制rs0

然后重新启动

sudo systemctl daemon-reload     //<--To reload service units
sudo systemctl restart mongod    //<--To Restart MongoDB Server
Run Code Online (Sandbox Code Playgroud)

然后通过终端中的 mongod 实例启动复制

$ mongosh
$ rs.initiate()
Run Code Online (Sandbox Code Playgroud)