linux+docker+nestjs+mongo事务处理

mongo事务处理仅适用于用于副本集环境,所以事务处理之前需要进行副本集环境的搭建。

Linux+docker+MongoDB集群环境搭建

# 1. 主机上运行,启动mongodb副本集3个节点
docker run -d --name mongo-master \
  -v /home/docker_data/db/mongo5/mongoreplset/mongo-master/db/:/data/db \
  -v /home/docker_data/db/mongo5/mongoreplset/mongo-master/configdb/:/data/configdb \
  -p 17020:27017 \
  mongo:5.0.1 \
  mongod --dbpath /data/db  --replSet mongoreplset --oplogSize 128

docker run -d --name mongo-salve \
  -v /home/docker_data/db/mongo5/mongoreplset/mongo-salve/db/:/data/db \
  -v /home/docker_data/db/mongo5/mongoreplset/mongo-salve/configdb/:/data/configdb \
  -p 17021:27017  \
  mongo:5.0.1 \
  mongod --dbpath /data/db  --replSet mongoreplset --oplogSize 128


docker run -d --rm --name mongo-arbiter \
  -v /home/docker_data/db/mongo5/mongoreplset/mongo-arbiter/db/:/data/db \
  -v /home/docker_data/db/mongo5/mongoreplset/mongo-arbiter/configdb/:/data/configdb \
  -p 17022:27017 \
  mongo:5.0.1 \
  mongod --dbpath /data/db  --replSet mongoreplset --oplogSize 128

    
# 2.集群配置
docker exec -it mongo-master mongo
config = {_id:"mongoreplset", version:1, members:[{_id:0, host:"192.168.128.157:17020", priority:5}, {_id:1, host:"192.168.128.157:17021", priority:2}, {_id:2, host:"192.168.128.157:17022", priority:3}]}
rs.initiate(config)

# 连接mongo
# mongodb://192.168.128.157:17020,192.168.128.157:17021,192.168.128.157:17022/supercook?replicaSet=mongoreplset
# mongoreplset: 为自定义的集群ID

 

window环境安装MongoDB副本集和使用:

npm install run-rs -g
run-rs -v 4.0.0
MONGO_URI=mongodb://DESKTOP-5D0LRKT:27017,DESKTOP-5D0LRKT:27018,DESKTOP-5D0LRKT:27019?replicaSet=rs

 

nestjs框架中配置MongoDB集群地址

MONGO_URI=mongodb://192.168.128.157:17020,192.168.128.157:17021,192.168.128.157:17022/supercook?replicaSet=mongoreplset

 

MongoDB事务工具类开发

src\helpers\modules\transaction.helper.ts

import { Injectable } from '@nestjs/common';
import { ClientSession } from 'mongoose';
import { InjectConnection } from '@nestjs/mongoose';
import { Connection } from 'mongoose';

@Injectable()
export class TransactionHelper {
  constructor(@InjectConnection() private connection: Connection) {}

  async startTransaction(): Promise<ClientSession> {
    const session: ClientSession = await this.connection.startSession();
    await session.startTransaction();
    return session;
  }

  async commitTransaction(session: ClientSession) {
    await session.commitTransaction();
    await session.endSession();
  }

  async rollbackTransaction(session: ClientSession) {
    await session.abortTransaction();
    await session.endSession();
  }
}

src\helpers\modules\init.module.ts

import { Module } from '@nestjs/common';
import { TransactionHelper } from './transaction.helper';

@Module({
  providers: [TransactionHelper],
  exports: [TransactionHelper],
})
export class InitModule {}

事务工具类的使用

src\helpers\helpers.controller.ts

import { Controller, Req } from '@nestjs/common';
import { Api } from 'src/common/decorators';
import { Request } from 'express';
import { TransactionHelper } from './modules/transaction.helper';
import { InjectConnection } from '@nestjs/mongoose';
import { Connection, Schema, Model } from 'mongoose';

@Controller('helpers')
export class HelpersController {

    constructor(
        private readonly transaction: TransactionHelper,
        @InjectConnection() private connection: Connection
    ) {}

    private Customer: Model<unknown>;


    @Api('transaction/test') 
    async testTransaction(@Req() req: Request) {
        if(this.Customer == null) {
            this.Customer = this.connection.model('transactionTest', new Schema({ name: String, createTime: Number }));
        }
        const { type } = req.body;
        const session = await this.transaction.startTransaction();
        const r = await this.Customer.create([{ name: 'Test', createTime: Date.now() }], { session: session });
        let id = r[0]._id;
        if(type == "commit") {
            await this.transaction.commitTransaction(session);
        } else {
            await this.transaction.rollbackTransaction(session);
        }
        return await this.Customer.findById(id);
    }
}

 

src\helpers\helpers.module.ts

import { Global, Module } from '@nestjs/common';
import { InitModule } from './modules/init.module';
import { TransactionHelper } from './modules/transaction.helper';
import { HelpersController } from './helpers.controller';
import { HelpersService } from './helpers.service';

@Global()
@Module({
  imports: [InitModule],
  providers: [HelpersService, HelpersService],
  exports: [HelpersService],
  controllers: [HelpersController],
})
export class HelpersModule {}

 

posted @ 2021-12-07 15:46  King雨  阅读(343)  评论(0)    收藏  举报