【问题标题】:Cosmos DB: Retryable writes are not supported. Please disable retryable writes by specifyingCosmos DB:不支持可重试写入。请通过指定禁用可重试写入
【发布时间】:2021-09-12 23:57:08
【问题描述】:

关于这个问题有很多线程,没有一个有适合我的解决方案。 我正在使用 NestJS、TypeORM 和 Cosmos DB Mongo API。

我在我的机器上运行 NestJS 服务,访问 Azure 中的数据库。 我可以很好地从集合中读取,但是每当我尝试写入时,我都会收到以下错误:

MongoError: Retryable writes are not supported. Please disable retryable writes by specifying "retrywrites=false" in the connection string or an equivalent driver specific config.

保存到数据库的逻辑的精简版本。我保存的对象在 Azure 的 Mongo Shell 中执行 db.collection.save() 时工作​​正常。但是完全相同的 save() 在这里失败了

@Injectable()
export class PatientService {

constructor(
    @InjectRepository(PatientsByUser)
    private readonly patientsByUserRepo: MongoRepository<PatientsByUser>
) {}

async addPatientToFavoritesList() {
            this.patientsByUserRepo.save({
                email: "test",
                patientList: [{
                    accountNumber: 1,
                    firstName: "test",
                    lastName: "test",
                    dob: "test"
                }]
            })
  }

}

这里是配置 TypeORM 的模块:

import {HttpModule, Module} from '@nestjs/common';
import {ConfigModule} from "@nestjs/config";
import {TypeOrmModule} from "@nestjs/typeorm";
import {PatientService} from "./patient.service";
import {PatientController} from "./patient.controller";
import {PatientsByUser} from "./patient.entity";

@Module({
    imports: [
        HttpModule,
        ConfigModule.forRoot(),
        TypeOrmModule.forRoot({
            type: 'mongodb',
            url: process.env.MONGODB_CONNECTION_STRING,
            database: process.env.MONGODB_DATABASE,
            entities: [
                __dirname + '/**/*.entity{.ts,.js}',
            ],
            ssl: true,
            useUnifiedTopology: true,
            useNewUrlParser: true,

        }),
        TypeOrmModule.forFeature([PatientsByUser])
    ],
    providers: [PatientService],
    controllers: [PatientController],
    exports: [PatientService]
})
export class PatientModule {}

我的连接字符串确实包含 retrywrites=false。我还尝试了 retryWrites=false,并在连接字符串的末尾都尝试了。都没有用。

MONGODB_CONNECTION_STRING=mongodb://portal-db-dev:<private>==@portal-db-dev.mongo.cosmos.azure.com:10255/?ssl=true&replicaSet=globaldb&retrywrites=false&maxIdleTimeMS=120000&appName=@portal-db-dev@

我们的 Cosmos DB 是第 4 版。我知道回滚到 3.2 可以解决这个问题,但如果这是唯一的出路,那将是次优的,而且在微软方面是完全荒谬的。

package.json

{
  "name": "portal-be",
  "version": "0.0.1",
  "description": "",
  "author": "",
  "private": true,
  "license": "UNLICENSED",
  "scripts": {
    "prebuild": "rimraf dist",
    "build": "nest build && mkdir dist/src/assets && cp -r src/assets/* dist/src/assets",
    "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
    "start": "nest start",
    "start:dev": "nest start --watch",
    "start:debug": "nest start --debug --watch",
    "start:prod": "node dist/main",
    "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
    "test": "jest",
    "test:watch": "jest --watch",
    "test:cov": "jest --coverage",
    "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
    "test:e2e": "jest --config ./test/jest-e2e.json"
  },
  "dependencies": {
    "@nestjs/common": "^7.6.13",
    "@nestjs/config": "^0.6.3",
    "@nestjs/core": "^7.6.13",
    "@nestjs/passport": "^7.1.5",
    "@nestjs/platform-express": "^7.6.13",
    "@nestjs/swagger": "^4.7.15",
    "@nestjs/typeorm": "^7.1.5",
    "@types/mongodb": "^3",
    "@types/passport-azure-ad": "^4.0.8",
    "class-transformer": "^0.4.0",
    "class-validator": "^0.13.1",
    "dotenv": "^8.2.0",
    "jwt-decode": "^3.1.2",
    "moment": "^2.29.1",
    "mongodb": "^3.6.9",
    "passport": "^0.4.1",
    "passport-azure-ad": "^4.3.0",
    "reflect-metadata": "^0.1.13",
    "rimraf": "^3.0.2",
    "rxjs": "^6.6.7",
    "soap": "^0.39.0",
    "typeorm": "^0.2.32"
  },
  "devDependencies": {
    "@nestjs/cli": "^7.5.6",
    "@nestjs/schematics": "^7.2.7",
    "@nestjs/testing": "^7.6.13",
    "@types/express": "^4.17.11",
    "@types/jest": "^26.0.20",
    "@types/mongodb": "^3",
    "@types/node": "^14.14.31",
    "@types/supertest": "^2.0.10",
    "@typescript-eslint/eslint-plugin": "^4.15.2",
    "@typescript-eslint/parser": "^4.15.2",
    "eslint": "^7.20.0",
    "eslint-config-prettier": "^8.1.0",
    "eslint-plugin-prettier": "^3.3.1",
    "jest": "^26.6.3",
    "prettier": "^2.2.1",
    "supertest": "^6.1.3",
    "ts-jest": "^26.5.2",
    "ts-loader": "^8.0.17",
    "ts-node": "^9.1.1",
    "tsconfig-paths": "^3.9.0",
    "typescript": "^4.1.5"
  },
  "jest": {
    "moduleFileExtensions": [
      "js",
      "json",
      "ts"
    ],
    "rootDir": "src",
    "testRegex": ".*\\.spec\\.ts$",
    "transform": {
      "^.+\\.(t|j)s$": "ts-jest"
    },
    "collectCoverageFrom": [
      "**/*.(t|j)s"
    ],
    "coverageDirectory": "../coverage",
    "testEnvironment": "node"
  }
}

【问题讨论】:

    标签: azure azure-cosmosdb nestjs typeorm azure-cosmosdb-mongoapi


    【解决方案1】:

    Cosmos DB 不支持可重试写入。

    mongo shell 默认不启用可重试写入。

    与 MongoDB 4.2 或更高版本兼容的 MongoDB 驱动程序默认启用可重试写入。

    MongoDB Node.JS 驱动程序版本 3.3+ 与 MongoDB 4.2 兼容

    要使用默认启用可重试写入的驱动程序连接到不支持可重试写入的数据库服务器,您需要通过在连接字符串 URI 中传递 retryWrites=false 来禁用可重试写入。

    https://docs.mongodb.com/manual/core/retryable-writes/#enabling-retryable-writes

    【讨论】:

    • 我已经把retryWrites=flase放在了连接字符串里,在post里。除此之外还有什么我可以尝试的吗?
    • 在帖子中,它全部显示为小写。确保大小写正确。
    • 我已经尝试了每种情况的所有可能组合。问题不在此标志之外。由于某种原因,NestJS 中的驱动程序不尊重该标志。回滚到 mongo 3.2 可以解决此问题,但使用 6 年旧版本的数据库不太理想
    猜你喜欢
    • 2022-01-12
    • 2021-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-30
    • 1970-01-01
    • 2020-02-23
    • 1970-01-01
    相关资源
    最近更新 更多